├── .gitignore ├── .metadata ├── .lock ├── .mylyn │ ├── .taskListIndex │ │ ├── segments_1 │ │ └── write.lock │ ├── .tasks.xml.zip │ ├── repositories.xml.zip │ └── tasks.xml.zip ├── .plugins │ ├── com.googlecode.goclipse.ui │ │ └── dialog_settings.xml │ ├── org.eclipse.cdt.make.core │ │ ├── specs.c │ │ └── specs.cpp │ ├── org.eclipse.core.resources │ │ ├── .root │ │ │ ├── .indexes │ │ │ │ ├── history.version │ │ │ │ ├── properties.index │ │ │ │ └── properties.version │ │ │ └── 2.tree │ │ └── .safetable │ │ │ └── org.eclipse.core.resources │ ├── org.eclipse.core.runtime │ │ └── .settings │ │ │ ├── org.eclipse.cdt.debug.core.prefs │ │ │ ├── org.eclipse.cdt.ui.prefs │ │ │ ├── org.eclipse.core.resources.prefs │ │ │ ├── org.eclipse.debug.core.prefs │ │ │ ├── org.eclipse.debug.ui.prefs │ │ │ ├── org.eclipse.epp.logging.aeri.ide.prefs │ │ │ ├── org.eclipse.epp.mpc.ui.prefs │ │ │ ├── org.eclipse.jdt.ui.prefs │ │ │ ├── org.eclipse.m2e.discovery.prefs │ │ │ ├── org.eclipse.mylyn.context.core.prefs │ │ │ ├── org.eclipse.mylyn.monitor.ui.prefs │ │ │ ├── org.eclipse.mylyn.tasks.ui.prefs │ │ │ ├── org.eclipse.team.ui.prefs │ │ │ ├── org.eclipse.ui.editors.prefs │ │ │ ├── org.eclipse.ui.ide.prefs │ │ │ ├── org.eclipse.ui.workbench.prefs │ │ │ └── org.python.pydev.prefs │ ├── org.eclipse.debug.ui │ │ └── dialog_settings.xml │ ├── org.eclipse.dltk.core │ │ └── Containers.dat │ ├── org.eclipse.e4.workbench │ │ └── workbench.xmi │ ├── org.eclipse.epp.logging.aeri.ide │ │ └── org.eclipse.epp.logging.aeri.ide.server │ │ │ ├── http-cache.lucene60 │ │ │ ├── segments_1 │ │ │ └── write.lock │ │ │ ├── local-history.lucene60 │ │ │ ├── _0.cfe │ │ │ ├── _0.cfs │ │ │ ├── _0.si │ │ │ ├── segments_1 │ │ │ └── write.lock │ │ │ └── server-config.json │ ├── org.eclipse.epp.mpc.ui │ │ └── dialog_settings.xml │ ├── org.eclipse.equinox.p2.ui │ │ └── dialog_settings.xml │ ├── org.eclipse.jdt.core │ │ ├── assumedExternalFilesCache │ │ ├── externalFilesCache │ │ ├── index.db │ │ ├── nonChainingJarsCache │ │ └── variablesAndContainers.dat │ ├── org.eclipse.jdt.ui │ │ ├── OpenTypeHistory.xml │ │ ├── QualifiedTypeNameHistory.xml │ │ └── dialog_settings.xml │ ├── org.eclipse.m2e.logback.configuration │ │ └── logback.1.8.2.20171007-0217.xml │ ├── org.eclipse.oomph.setup │ │ └── workspace.setup │ ├── org.eclipse.recommenders.news.impl │ │ └── downloads │ │ │ ├── http%3A%2F%2Fwww.eclipse.org%2Fhome%2Feclipsenews.rss │ │ │ └── http%3A%2F%2Fwww.eclipse.org%2Frecommenders%2Ffeeds%2Fide.rss │ ├── org.eclipse.ui.editors │ │ └── dialog_settings.xml │ ├── org.eclipse.ui.intro │ │ └── introstate │ ├── org.eclipse.ui.workbench │ │ ├── dialog_settings.xml │ │ └── workingsets.xml │ └── org.python.pydev │ │ └── pyunit_tests │ │ └── test_run_pin_info.txt └── version.ini ├── .project ├── .vscode ├── launch.json └── settings.json ├── AlgorithmsChapters ├── BT │ ├── GraphColouring.go │ ├── NQueen.go │ ├── Permutations.go │ ├── SubsetSum.go │ ├── TOH.go │ └── TSP.go ├── CA │ └── IsPrime.go ├── DAC │ ├── ClosestPair.go │ ├── NutsAndBolts.go │ └── pow.go ├── DP │ ├── ALS.go │ ├── CoinChange.go │ ├── DiceThrow.go │ ├── EditDist.go │ ├── Fibo.go │ ├── FloydWarshall.go │ ├── GridMinCost.go │ ├── GridUniqueWays.go │ ├── HouseRobber.go │ ├── JobScheduling.go │ ├── Knapsack.go │ ├── LargestBitonicSubseq.go │ ├── LargestIncreasingSubseq.go │ ├── LargestPalindromicSubsequence.go │ ├── LargestPalindromicSubstr.go │ ├── LongestCommonSubseq.go │ ├── MatrixCM.go │ ├── MinCostBinaryTree.go │ ├── MinStairCost.go │ ├── OptimalBST.go │ ├── StairUniqueWays.go │ ├── StockBuySell.go │ ├── Vacation.go │ └── WildCharMatch.go └── Greedy │ ├── ActivitySelection.go │ ├── ChotaBhim.go │ ├── FractionalKnapsack.go │ ├── HuffmanTree.go │ ├── JobSequencing.go │ ├── JoinRopes.go │ ├── Knapsack.go │ ├── MultipleStageGraph.go │ └── OptimalMergePattern.go ├── Basics ├── AccesserModifier.go ├── Array.go ├── Bulb.go ├── For.go ├── Helloworld.go ├── Limit.go ├── LinkedList.go ├── Shape.go ├── Tree.go ├── if.go ├── pointer.go ├── range.go ├── string.go ├── switch.go ├── text.txt ├── untitled.go └── variable.go ├── Collections ├── Array.go ├── Counter.go ├── Heap.go ├── Map.go ├── Queue.go ├── Set.go ├── Set2.go └── Stack.go ├── Graph ├── Graph.go ├── GraphAM.go └── hp.go ├── HashTable ├── HashTableExercise.go ├── HashTableLP.go └── HashTableSC.go ├── Heap ├── Heap.go └── heap2.go ├── IntroductoryChapters ├── Analysis.go └── Intro.go ├── LinkedLIst ├── CircularLinkedList.go ├── DoublyCircularLIst.go ├── DoublyLinkedList.go ├── LinkedLIst.go └── Polynomial.go ├── Queue ├── Queue.go ├── QueueEX.go ├── QueueLL.go ├── QueueLinkedLIst.go ├── QueueUsingStack.go └── StackUsingQueue.go ├── README.md ├── Searching ├── BitManipulation.go └── Searching.go ├── Sorting ├── BubbleSort.go ├── BucketSort.go ├── CountSort.go ├── InsertionSort.go ├── MergeSort.go ├── QuickSelect.go ├── QuickSort.go ├── RadixSort.go ├── SelectionSort.go ├── ShellSort.go └── SortingEx.go ├── Stack ├── Stack.go ├── StackExercise.go ├── StackLL.go └── StackLinkedList.go ├── String ├── StringEx.go ├── StringMatching.go ├── StringTree.go ├── TST.go └── Trie.go ├── Tree ├── AVLTree.go ├── BTree.go ├── BinaryIndexTree.go ├── RBTree.go ├── SPLAYTree.go ├── SegmentTree.go ├── Tree.go ├── rangeMaxST.go └── rmqST.go └── script.sh /.gitignore: -------------------------------------------------------------------------------- 1 | BinaryTree/debug 2 | *.exe 3 | *.log 4 | *.log 5 | -------------------------------------------------------------------------------- /.metadata/.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.lock -------------------------------------------------------------------------------- /.metadata/.mylyn/.taskListIndex/segments_1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.mylyn/.taskListIndex/segments_1 -------------------------------------------------------------------------------- /.metadata/.mylyn/.taskListIndex/write.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.mylyn/.taskListIndex/write.lock -------------------------------------------------------------------------------- /.metadata/.mylyn/.tasks.xml.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.mylyn/.tasks.xml.zip -------------------------------------------------------------------------------- /.metadata/.mylyn/repositories.xml.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.mylyn/repositories.xml.zip -------------------------------------------------------------------------------- /.metadata/.mylyn/tasks.xml.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.mylyn/tasks.xml.zip -------------------------------------------------------------------------------- /.metadata/.plugins/com.googlecode.goclipse.ui/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.cdt.make.core/specs.c: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index: -------------------------------------------------------------------------------- 1 | /org.eclipse.jdt.corestateVersionNumber30 -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.resources/.root/2.tree: -------------------------------------------------------------------------------- 1 | org.eclipse.dltk.coreorg.eclipse.cdt.coreorg.eclipse.jdt.core -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.cdt.debug.core.cDebug.default_source_containers=\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | spelling_locale_initialized=true 3 | useAnnotationsPrefPage=true 4 | useQuickDiffPrefPage=true 5 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | version=1 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs: -------------------------------------------------------------------------------- 1 | //org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.applicationLaunchType=org.eclipse.cdt.dsf.gdb.launch.localCLaunch,debug,;org.eclipse.cdt.cdi.launch.localCLaunch,run,; 2 | //org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.attachLaunchType=org.eclipse.cdt.dsf.gdb.launch.attachCLaunch,debug,; 3 | //org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.postmortemLaunchType=org.eclipse.cdt.dsf.gdb.launch.coreCLaunch,debug,; 4 | eclipse.preferences.version=1 5 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=\r\n\r\n 3 | preferredTargets=com.googlecode.goclipse.coreBreakpointFactory,com.googlecode.goclipse.uiDynamicPrintfBreakpointFactory\:com.googlecode.goclipse.coreBreakpointFactory| 4 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.epp.logging.aeri.ide.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | resetSendMode=KEEP 3 | resetSendModeOn=0 4 | sendMode=NOTIFY 5 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.epp.mpc.ui.prefs: -------------------------------------------------------------------------------- 1 | CatalogDescriptor=http\://marketplace.eclipse.org 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | content_assist_proposals_background=255,255,255 2 | content_assist_proposals_foreground=0,0,0 3 | eclipse.preferences.version=1 4 | org.eclipse.jdt.ui.formatterprofiles.version=13 5 | spelling_locale_initialized=true 6 | useAnnotationsPrefPage=true 7 | useQuickDiffPrefPage=true 8 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.m2e.discovery.pref.projects= 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | mylyn.attention.migrated=true 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | migrated.task.repositories.secure.store=true 3 | org.eclipse.mylyn.tasks.ui.filters.nonmatching=true 4 | org.eclipse.mylyn.tasks.ui.filters.nonmatching.encouraged=true 5 | org.eclipse.mylyn.tasks.ui.welcome.message=true 6 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.team.ui.first_time=false 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | overviewRuler_migration=migrated_3.1 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs: -------------------------------------------------------------------------------- 1 | PROBLEMS_FILTERS_MIGRATE=true 2 | eclipse.preferences.version=1 3 | platformState=1517312887711 4 | quickStart=false 5 | tipsAndTricks=true 6 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs: -------------------------------------------------------------------------------- 1 | //org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false 2 | PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery; 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs: -------------------------------------------------------------------------------- 1 | INTERPRETERS_CHECKED_ONCE=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.dltk.core/Containers.dat: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/http-cache.lucene60/segments_1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/http-cache.lucene60/segments_1 -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/http-cache.lucene60/write.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/http-cache.lucene60/write.lock -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.cfe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.cfe -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.cfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.cfs -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.si: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/_0.si -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/segments_1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/segments_1 -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/write.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/local-history.lucene60/write.lock -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.logging.aeri.ide/org.eclipse.epp.logging.aeri.ide.server/server-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v1", 3 | "title": "Eclipse", 4 | "timestamp": 1521361318772, 5 | "ttl": 10080, 6 | "helpUrl": "https://dev.eclipse.org/recommenders/community/aeri/v2/help/", 7 | "feedbackUrl": "https://www.codetrails.com/error-analytics/", 8 | "aboutUrl": "https://wiki.eclipse.org/EPP/Logging", 9 | "submitUrl": "https://dev.eclipse.org/recommenders/community/confess/0.6/reports/", 10 | "maxReportSize": 262144, 11 | "problemsUrl": "https://www.eclipse.org/downloads/download.php?r\u003d1\u0026file\u003d/technology/epp/logging/problems.zip", 12 | "problemsTtl": 20160, 13 | "interestUrl": "https://dev.eclipse.org/recommenders/community/confess/v2/interest", 14 | "connectTimeout": 10, 15 | "socketTimeout": 10, 16 | "acceptedProducts": [ 17 | "org.eclipse.*", 18 | "org.fordiac.*" 19 | ], 20 | "acceptedPlugins": [ 21 | "org.apache.log4j.*", 22 | "org.eclipse.*", 23 | "org.fordiac.*" 24 | ], 25 | "acceptedPackages": [ 26 | "ch.qos.*", 27 | "com.cforcoding.*", 28 | "com.google.*", 29 | "com.gradleware.tooling.*", 30 | "com.mountainminds.eclemma.*", 31 | "com.naef.*", 32 | "com.sun.*", 33 | "java.*", 34 | "javafx.*", 35 | "javax.*", 36 | "org.apache.*", 37 | "org.eclipse.*", 38 | "org.fordiac.*", 39 | "org.gradle.*", 40 | "org.jacoco.*", 41 | "org.osgi.*", 42 | "org.slf4j.*", 43 | "sun.*" 44 | ], 45 | "requiredPackages": [ 46 | "com.cforcoding.*", 47 | "com.gradleware.tooling.*", 48 | "com.mountainminds.eclemma.*", 49 | "com.naef.*", 50 | "org.eclipse.*", 51 | "org.fordiac.*", 52 | "org.gradle.*", 53 | "org.jacoco.*" 54 | ], 55 | "acceptOtherPackages": false, 56 | "acceptUiFreezes": true, 57 | "ignoredStatuses": [ 58 | ":java.io.IOException:There is not enough space on the disk", 59 | ":java.net.*:", 60 | "org.eclipse.core.filesystem::Could not delete*", 61 | "org.eclipse.core.filesystem::Could not move*", 62 | "org.eclipse.core.resources:org.eclipse.core.internal.resources.ResourceException:Resource is out of sync with the file system*", 63 | "org.eclipse.core.runtime::Invalid input url*", 64 | "org.eclipse.epp.mpc.ui:java.io.IOException:", 65 | "org.eclipse.equinox.p2.*::", 66 | "org.eclipse.jface:java.io.IOException:Unable to resolve plug-in*", 67 | "org.eclipse.oomph.setup.core:$org.apache.http.ConnectionClosedException:", 68 | "org.eclipse.pde.core::The current target platform contains errors*", 69 | "org.eclipse.ui::Conflicting handlers for*" 70 | ], 71 | "problemsZipLastDownloadTimestamp": 0 72 | } -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.epp.mpc.ui/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.equinox.p2.ui/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.core/index.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hemant-Jain-Author/Data-Structures-Algorithms-In-Go/72cbfe8785578813e1505928acff376cb1e3f57c/.metadata/.plugins/org.eclipse.jdt.core/index.db -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat: -------------------------------------------------------------------------------- 1 | JRE_LIB JRE_SRCROOT 2 | JUNIT_HOMEJRE_SRCJUNIT_SRC_HOMEM2_REPO -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.8.2.20171007-0217.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %date [%thread] %-5level %logger{35} - %msg%n 5 | 6 | 7 | OFF 8 | 9 | 10 | 11 | 12 | ${org.eclipse.m2e.log.dir}/0.log 13 | 14 | ${org.eclipse.m2e.log.dir}/%i.log 15 | 1 16 | 10 17 | 18 | 19 | 100MB 20 | 21 | 22 | %date [%thread] %-5level %logger{35} - %msg%n 23 | 24 | 25 | 26 | 27 | 28 | WARN 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.recommenders.news.impl/downloads/http%3A%2F%2Fwww.eclipse.org%2Frecommenders%2Ffeeds%2Fide.rss: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code Recommenders In-IDE News 5 | https://www.eclipse.org/recommenders/ 6 | The latest news about Code Recommenders, delivered to your Eclipse IDE 7 | 8 | Insert Knowledge Here - A Guide to Intelligent Code Completion Using Eclipse Code Recommenders 9 | https://medium.com/codetrails/insert-knowledge-here-a2f71c2862d2?utm_source=rss-eclipse&utm_medium=eclipse&utm_campaign=cc 10 | Tue, 10 Oct 2017 16:00:00 GMT 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.ui.editors/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.ui.intro/introstate: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.metadata/.plugins/org.python.pydev/pyunit_tests/test_run_pin_info.txt: -------------------------------------------------------------------------------- 1 | || -------------------------------------------------------------------------------- /.metadata/version.ini: -------------------------------------------------------------------------------- 1 | #Sun Mar 18 13:59:22 IST 2018 2 | org.eclipse.core.runtime=2 3 | org.eclipse.platform=4.7.2.v20171130-0510 4 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Data-Structures-Algorithms-In-Go 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch file", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "debug", 12 | "program": "${file}" 13 | }, 14 | { 15 | "name": "Listen for XDebug", 16 | "type": "php", 17 | "request": "launch", 18 | "port": 9000 19 | }, 20 | { 21 | "name": "Launch currently open script", 22 | "type": "php", 23 | "request": "launch", 24 | "program": "${file}", 25 | "cwd": "${fileDirname}", 26 | "port": 9000 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "curr", 4 | "Unweghted" 5 | ] 6 | } -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/GraphColouring.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func GraphColouring(graph [][]bool, V int, m int) bool { 6 | colour := make([]int, V) 7 | if graphColouringUtil(graph, V, m, colour, 0) { 8 | fmt.Println("Assigned colours are:", colour) 9 | return true 10 | } 11 | fmt.Println("Solution does not exist") 12 | return false 13 | } 14 | 15 | func graphColouringUtil(graph [][]bool, V int, m int, colour []int, i int) bool { 16 | if i == V { 17 | return true 18 | } 19 | 20 | for j := 1; j <= m; j++ { 21 | if isGraphColouredProperly(graph, V, colour, i, j) { 22 | colour[i] = j 23 | if graphColouringUtil(graph, V, m, colour, i+1) { 24 | return true 25 | } 26 | } 27 | } 28 | 29 | return false 30 | } 31 | 32 | // Check if the whole graph is coloured properly. 33 | func isGraphColouredProperly(graph [][]bool, V int, colour []int, v int, c int) bool { 34 | for i := 0; i < V; i++ { 35 | if graph[v][i] && c == colour[i] { 36 | return false 37 | } 38 | } 39 | return true 40 | } 41 | 42 | func GraphColouring2(graph [][]bool, V int, m int) bool { 43 | colour := make([]int, V) 44 | if graphColouringUtil2(graph, V, m, colour, 0) { 45 | fmt.Println("Assigned colours are:", colour) 46 | return true 47 | } 48 | fmt.Println("Solution does not exist") 49 | return false 50 | } 51 | 52 | func graphColouringUtil2(graph [][]bool, V int, m int, colour []int, i int) bool { 53 | if i == V { 54 | return isGraphColouredProperly2(graph, colour, V) 55 | } 56 | 57 | for j := 1; j <= m; j++ { 58 | colour[i] = j 59 | if graphColouringUtil2(graph, V, m, colour, i+1) { 60 | return true 61 | } 62 | } 63 | 64 | return false 65 | } 66 | 67 | // Check if the whole graph is coloured properly. 68 | func isGraphColouredProperly2(graph [][]bool, colour []int, V int) bool { 69 | for i := 0; i < V; i++ { 70 | for j := i + 1; j < V; j++ { 71 | if graph[i][j] && colour[j] == colour[i] { 72 | return false 73 | } 74 | } 75 | } 76 | return true 77 | } 78 | 79 | // Testing code. 80 | func main() { 81 | graph := [][]bool{ 82 | {false, true, false, false, true}, 83 | {true, false, true, false, true}, 84 | {false, true, false, true, true}, 85 | {false, false, true, false, true}, 86 | {true, true, true, true, false}, 87 | } 88 | V := 5 89 | m := 4 90 | 91 | GraphColouring(graph, V, m) 92 | GraphColouring2(graph, V, m) 93 | } 94 | 95 | /* 96 | Assigned colours are: [1 2 1 2 3] 97 | Assigned colours are: [1 2 1 2 3] 98 | */ 99 | -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/NQueen.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func NQueens(n int) { 9 | board := make([]int, n) 10 | nQueensUtil(board, 0, n) 11 | } 12 | 13 | func nQueensUtil(board []int, col int, n int) { 14 | if col == n { 15 | fmt.Println(board) 16 | return 17 | } 18 | 19 | for row := 0; row < n; row++ { 20 | board[col] = row 21 | if isSafe(board, col) { 22 | nQueensUtil(board, col+1, n) 23 | } 24 | } 25 | } 26 | 27 | func isSafe(board []int, col int) bool { 28 | for i := 0; i < col; i++ { 29 | if board[col] == board[i] || math.Abs(float64(board[col]-board[i])) == float64(col-i) { 30 | return false 31 | } 32 | } 33 | return true 34 | } 35 | 36 | // Testing code. 37 | func main() { 38 | NQueens(8) 39 | } 40 | 41 | /* 42 | [0 4 7 5 2 6 1 3] 43 | [0 5 7 2 6 3 1 4] 44 | ....... 45 | [7 2 0 5 1 4 6 3] 46 | [7 3 0 2 5 1 6 4] 47 | */ 48 | -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/Permutations.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func Permutation(arr []int, i int, length int) { 9 | if length == i { 10 | fmt.Println(arr) 11 | return 12 | } 13 | for j := i; j < length; j++ { 14 | arr[i], arr[j] = arr[j], arr[i] 15 | Permutation(arr, i+1, length) 16 | arr[i], arr[j] = arr[j], arr[i] 17 | } 18 | } 19 | 20 | func Permutation2(arr []int, i int, length int) { 21 | if length == i { 22 | if isValid(arr, length) { 23 | fmt.Println(arr) 24 | } 25 | return 26 | } 27 | for j := i; j < length; j++ { 28 | arr[i], arr[j] = arr[j], arr[i] 29 | Permutation2(arr, i+1, length) 30 | arr[i], arr[j] = arr[j], arr[i] 31 | } 32 | } 33 | 34 | func isValid(arr []int, n int) bool { 35 | for j := 1; j < n; j++ { 36 | if math.Abs(float64(arr[j]-arr[j-1])) < 2 { 37 | return false 38 | } 39 | } 40 | return true 41 | } 42 | 43 | func Permutation3(arr []int, i int, length int) { 44 | if length == i { 45 | fmt.Println(arr) 46 | return 47 | } 48 | for j := i; j < length; j++ { 49 | arr[i], arr[j] = arr[j], arr[i] 50 | if isValid2(arr, i) { 51 | Permutation3(arr, i+1, length) 52 | } 53 | arr[i], arr[j] = arr[j], arr[i] 54 | } 55 | } 56 | 57 | func isValid2(arr []int, i int) bool { 58 | if i < 1 || math.Abs(float64(arr[i]-arr[i-1])) >= 2 { 59 | return true 60 | } 61 | return false 62 | } 63 | 64 | func main() { 65 | arr := []int{1, 2, 3, 4} 66 | 67 | fmt.Println("Permutation:") 68 | Permutation(arr, 0, len(arr)) 69 | fmt.Println() 70 | 71 | fmt.Println("Valid Permutation:") 72 | Permutation2(arr, 0, len(arr)) 73 | fmt.Println() 74 | 75 | fmt.Println("Valid Adjacent Permutation:") 76 | Permutation3(arr, 0, len(arr)) 77 | } 78 | 79 | /* 80 | [1 2 3 4] 81 | [1 2 4 3] 82 | .... 83 | [4 1 3 2] 84 | [4 1 2 3] 85 | 86 | [2 4 1 3] 87 | [3 1 4 2] 88 | 89 | [2 4 1 3] 90 | [3 1 4 2] 91 | */ 92 | -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/SubsetSum.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func SubsetSum(arr []int, n int, target int) { 6 | flags := make([]bool, n) 7 | subsetSumUtil(arr, n, flags, 0, 0, target) 8 | } 9 | 10 | func subsetSumUtil(arr []int, n int, flags []bool, sum int, curr int, target int) { 11 | if sum == target { 12 | printSubset(flags, arr, n) 13 | return 14 | } 15 | if curr >= n || sum > target { 16 | return 17 | } 18 | flags[curr] = true 19 | subsetSumUtil(arr, n, flags, sum+arr[curr], curr+1, target) 20 | flags[curr] = false 21 | subsetSumUtil(arr, n, flags, sum, curr+1, target) 22 | } 23 | 24 | func printSubset(flags []bool, arr []int, size int) { 25 | for i := 0; i < size; i++ { 26 | if flags[i] { 27 | fmt.Print(arr[i], " ") 28 | } 29 | } 30 | fmt.Println() 31 | } 32 | 33 | func main() { 34 | arr := []int{15, 22, 14, 26, 32, 9, 16, 8} 35 | target := 53 36 | n := len(arr) 37 | SubsetSum(arr, n, target) 38 | } 39 | 40 | /* 41 | 15 22 16 42 | 15 14 16 8 43 | 22 14 9 8 44 | */ 45 | -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/TOH.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func TowerOfHanoi(num int) { 6 | fmt.Println("The sequence of moves involved in the Tower of Hanoi are :") 7 | tohUtil(num, "A", "C", "B") 8 | } 9 | 10 | func tohUtil(num int, from string, to string, temp string) { 11 | if num < 1 { 12 | return 13 | } 14 | tohUtil(num-1, from, temp, to) 15 | fmt.Println("Move disk ", num, " from peg ", from, " to peg ", to) 16 | tohUtil(num-1, temp, to, from) 17 | } 18 | 19 | // Testing code. 20 | func main() { 21 | TowerOfHanoi(3) 22 | } 23 | 24 | /* 25 | The sequence of moves involved in the Tower of Hanoi are : 26 | Move disk 1 from peg A to peg C 27 | Move disk 2 from peg A to peg B 28 | Move disk 1 from peg C to peg B 29 | Move disk 3 from peg A to peg C 30 | Move disk 1 from peg B to peg A 31 | Move disk 2 from peg B to peg C 32 | Move disk 1 from peg A to peg C 33 | */ -------------------------------------------------------------------------------- /AlgorithmsChapters/BT/TSP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | // Function to find the minimum weight Hamiltonian Cycle 9 | func TSP(graph [][]int, n int) int { 10 | visited := make([]bool, n) 11 | path := make([]int, n) 12 | ansPath := make([]int, n+1) 13 | path[0] = 0 14 | visited[0] = true 15 | ans := math.MaxInt64 16 | ans = tspUtil(graph, n, path, 1, 0, visited, ans, ansPath) 17 | fmt.Println("Path length:", ans) 18 | fmt.Print("Path: ") 19 | for i := 0; i <= n; i++ { 20 | fmt.Print(ansPath[i], " ") 21 | } 22 | return ans 23 | } 24 | 25 | func tspUtil(graph [][]int, n int, path []int, pSize int, pCost int, visited []bool, ans int, ansPath []int) int { 26 | if pCost > ans { 27 | return ans 28 | } 29 | 30 | curr := path[pSize-1] 31 | if pSize == n { 32 | if graph[curr][0] > 0 && ans > pCost+graph[curr][0] { 33 | ans = pCost + graph[curr][0] 34 | copy(ansPath, path) 35 | } 36 | return ans 37 | } 38 | 39 | for i := 0; i < n; i++ { 40 | if !visited[i] && graph[curr][i] > 0 { 41 | visited[i] = true 42 | path[pSize] = i 43 | ans = tspUtil(graph, n, path, pSize+1, pCost+graph[curr][i], visited, ans, ansPath) 44 | visited[i] = false 45 | } 46 | } 47 | return ans 48 | } 49 | 50 | // Testing code. 51 | func main() { 52 | n := 4 53 | graph := [][]int{ 54 | {0, 10, 15, 20}, 55 | {10, 0, 35, 25}, 56 | {15, 35, 0, 30}, 57 | {20, 25, 30, 0}, 58 | } 59 | TSP(graph, n) 60 | } 61 | 62 | /* 63 | Path length: 80 64 | Path: 0 1 3 2 0 65 | */ 66 | -------------------------------------------------------------------------------- /AlgorithmsChapters/CA/IsPrime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func IsPrime(n int) bool { 6 | if n < 2 { 7 | return false 8 | } 9 | 10 | for i := 2; i*i <= n; i++ { 11 | if n%i == 0 { 12 | return false 13 | } 14 | } 15 | return true 16 | } 17 | 18 | func main() { 19 | fmt.Println("7:", IsPrime(7)) 20 | fmt.Println("8:", IsPrime(8)) 21 | } 22 | 23 | /* 24 | 7: true 25 | 8: false 26 | */ 27 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DAC/ClosestPair.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "sort" 7 | ) 8 | 9 | type Point struct { 10 | x int 11 | y int 12 | } 13 | 14 | func NewPoint(a, b int) *Point { 15 | return &Point{x: a, y: b} 16 | } 17 | 18 | func distance(a, b *Point) float64 { 19 | return math.Sqrt(float64((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y))) 20 | } 21 | 22 | func ClosestPairBF(arr [][]int) float64 { 23 | n := len(arr) 24 | dMin := math.MaxFloat64 25 | 26 | for i := 0; i < n-1; i++ { 27 | for j := i + 1; j < n; j++ { 28 | d := distance(NewPoint(arr[i][0], arr[i][1]), NewPoint(arr[j][0], arr[j][1])) 29 | if d < dMin { 30 | dMin = d 31 | } 32 | } 33 | } 34 | 35 | return dMin 36 | } 37 | 38 | func ClosestPairDC(arr [][]int) float64 { 39 | n := len(arr) 40 | p := make([]*Point, n) 41 | for i := 0; i < n; i++ { 42 | p[i] = NewPoint(arr[i][0], arr[i][1]) 43 | } 44 | 45 | sort.Slice(p, func(i, j int) bool { 46 | return p[i].x < p[j].x 47 | }) 48 | 49 | q := make([]*Point, n) 50 | copy(q, p) 51 | 52 | sort.Slice(p, func(i, j int) bool { 53 | return p[i].y < p[j].y 54 | }) 55 | 56 | return closestPairUtil(p, 0, n-1, q, n) 57 | } 58 | 59 | func closestPairUtil(p []*Point, start int, stop int, q []*Point, n int) float64 { 60 | if stop-start < 1 { 61 | return math.MaxFloat64 62 | } 63 | if stop-start == 1 { 64 | return distance(p[start], p[stop]) 65 | } 66 | mid := (start + stop) / 2 67 | dl := closestPairUtil(p, start, mid, q, n) 68 | dr := closestPairUtil(p, mid+1, stop, q, n) 69 | d := math.Min(dl, dr) 70 | strip := make([]*Point, n) 71 | j := 0 72 | for i := 0; i < n; i++ { 73 | if math.Abs(float64(q[i].x-p[mid].x)) < d { 74 | strip[j] = q[i] 75 | j++ 76 | } 77 | } 78 | return math.Min(d, stripMin(strip, j, d)) 79 | } 80 | 81 | func stripMin(q []*Point, n int, d float64) float64 { 82 | min := d 83 | for i := 0; i < n; i++ { 84 | for j := i + 1; j < n && float64(q[j].y-q[i].y) < min; j++ { 85 | dist := distance(q[i], q[j]) 86 | if dist < min { 87 | min = dist 88 | } 89 | } 90 | } 91 | return min 92 | } 93 | 94 | func main() { 95 | arr := [][]int{{648, 896}, {269, 879}, {250, 922}, {453, 347}, {213, 17}} 96 | fmt.Println("Smallest distance is:", ClosestPairBF(arr)) 97 | fmt.Println("Smallest distance is:", ClosestPairDC(arr)) 98 | } 99 | 100 | /* 101 | Smallest distance is: 47.01063709417264 102 | Smallest distance is: 47.01063709417264 103 | */ 104 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DAC/NutsAndBolts.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func MakePairs(nuts []int, bolts []int) { 8 | if len(nuts) != len(bolts) { 9 | fmt.Println("Mismatched sizes of nuts and bolts") 10 | return 11 | } 12 | makePairsUtil(nuts, bolts, 0, len(nuts)-1) 13 | fmt.Print("Matched nuts and bolts are: ", nuts, " & ", bolts) 14 | } 15 | 16 | func makePairsUtil(nuts []int, bolts []int, low int, high int) { 17 | if low < high { 18 | pivot := partition(nuts, low, high, bolts[low]) 19 | partition(bolts, low, high, nuts[pivot]) 20 | makePairsUtil(nuts, bolts, low, pivot-1) 21 | makePairsUtil(nuts, bolts, pivot+1, high) 22 | } 23 | } 24 | 25 | func partition(arr []int, low int, high int, pivot int) int { 26 | i := low 27 | for j := low; j < high; j++ { 28 | if arr[j] < pivot { 29 | swap(arr, i, j) 30 | i++ 31 | } else if arr[j] == pivot { 32 | swap(arr, j, high) 33 | j-- 34 | } 35 | } 36 | swap(arr, i, high) 37 | return i 38 | } 39 | 40 | func swap(arr []int, first int, second int) { 41 | arr[first], arr[second] = arr[second], arr[first] 42 | } 43 | 44 | func main() { 45 | nuts := []int{1, 2, 6, 5, 4, 3} 46 | bolts := []int{6, 4, 5, 1, 3, 2} 47 | MakePairs(nuts, bolts) 48 | } 49 | 50 | /* 51 | Matched nuts and bolts are: [1 2 3 4 5 6] & [1 2 3 4 5 6] 52 | */ 53 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DAC/pow.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func power(x, n int) int { 6 | if n == 0 { 7 | return 1 8 | } 9 | 10 | value := power(x, n/2) 11 | result := value * value 12 | 13 | if n%2 == 1 { 14 | result *= x 15 | } 16 | 17 | return result 18 | } 19 | 20 | func main() { 21 | fmt.Println(power(5, 2)) 22 | } 23 | 24 | /* 25 | 25 26 | */ 27 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/ALS.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func min(a, b int) int { 6 | if a < b { 7 | return a 8 | } 9 | return b 10 | } 11 | 12 | func FastestWayBU(a, t [][]int, e, x []int, n int) int { 13 | f := make([][]int, 2) 14 | for i := range f { 15 | f[i] = make([]int, n) 16 | } 17 | 18 | // Time taken to leave the first station. 19 | f[0][0] = e[0] + a[0][0] 20 | f[1][0] = e[1] + a[1][0] 21 | 22 | // Fill the tables f1[] and f2[] using a bottom-up approach. 23 | for i := 1; i < n; i++ { 24 | f[0][i] = min(f[0][i-1]+a[0][i], f[1][i-1]+t[1][i-1]+a[0][i]) 25 | f[1][i] = min(f[1][i-1]+a[1][i], f[0][i-1]+t[0][i-1]+a[1][i]) 26 | } 27 | 28 | return min(f[0][n-1]+x[0], f[1][n-1]+x[1]) 29 | } 30 | 31 | func FastestWayBU2(a, t [][]int, e, x []int, n int) int { 32 | f1 := make([]int, n) 33 | f2 := make([]int, n) 34 | 35 | // Time taken to leave the first station. 36 | f1[0] = e[0] + a[0][0] 37 | f2[0] = e[1] + a[1][0] 38 | 39 | // Fill the tables f1[] and f2[] using a bottom-up approach. 40 | for i := 1; i < n; i++ { 41 | f1[i] = min(f1[i-1]+a[0][i], f2[i-1]+t[1][i-1]+a[0][i]) 42 | f2[i] = min(f2[i-1]+a[1][i], f1[i-1]+t[0][i-1]+a[1][i]) 43 | } 44 | 45 | return min(f1[n-1]+x[0], f2[n-1]+x[1]) 46 | } 47 | 48 | func FastestWayTD(a, t [][]int, e, x []int, n int) int { 49 | f := make([][]int, 2) 50 | for i := range f { 51 | f[i] = make([]int, n) 52 | } 53 | 54 | // Time taken to leave the first station. 55 | f[0][0] = e[0] + a[0][0] 56 | f[1][0] = e[1] + a[1][0] 57 | 58 | fastestWayUtilTD(f, a, t, n-1) 59 | return min(f[0][n-1]+x[0], f[1][n-1]+x[1]) 60 | } 61 | 62 | func fastestWayUtilTD(f, a, t [][]int, i int) { 63 | if i == 0 { 64 | return 65 | } 66 | fastestWayUtilTD(f, a, t, i-1) 67 | // Fill the tables f1[] and f2[] using a top-down approach. 68 | f[0][i] = min(f[0][i-1]+a[0][i], f[1][i-1]+t[1][i-1]+a[0][i]) 69 | f[1][i] = min(f[1][i-1]+a[1][i], f[0][i-1]+t[0][i-1]+a[1][i]) 70 | } 71 | 72 | func main() { 73 | a := [][]int{{7, 9, 3, 4, 8, 4}, {8, 5, 6, 4, 5, 7}} 74 | t := [][]int{{2, 3, 1, 3, 4}, {2, 1, 2, 2, 1}} 75 | e := []int{2, 4} 76 | x := []int{3, 2} 77 | n := 6 78 | 79 | fmt.Println("FastestWayBU:", FastestWayBU(a, t, e, x, n)) 80 | fmt.Println("FastestWayBU2:", FastestWayBU2(a, t, e, x, n)) 81 | fmt.Println("FastestWayTD:", FastestWayTD(a, t, e, x, n)) 82 | } 83 | 84 | /* 85 | FastestWayBU: 38 86 | FastestWayBU2: 38 87 | FastestWayTD: 38 88 | */ 89 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/CoinChange.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "sort" 7 | "strconv" 8 | ) 9 | 10 | // Greedy 11 | func MinCoins(coins []int, n int, val int) int { 12 | if val <= 0 { 13 | return 0 14 | } 15 | count := 0 16 | sort.Slice(coins, func(i, j int) bool { return coins[i] < coins[j] }) 17 | for i := n - 1; i >= 0 && val > 0; { 18 | if coins[i] <= val { 19 | count++ 20 | val -= coins[i] 21 | } else { 22 | i-- 23 | } 24 | } 25 | if val == 0 { 26 | return count 27 | } 28 | return -1 29 | } 30 | 31 | // Brute Force 32 | func MinCoins2(coins []int, n int, val int) int { 33 | if val == 0 { 34 | return 0 35 | } 36 | 37 | count := math.MaxInt32 38 | for i := 0; i < n; i++ { 39 | if coins[i] <= val { 40 | subCount := MinCoins2(coins, n, val-coins[i]) 41 | if subCount >= 0 { 42 | count = min(count, subCount+1) 43 | } 44 | } 45 | } 46 | if count != math.MaxInt32 { 47 | return count 48 | } 49 | return -1 50 | } 51 | 52 | func MinCoinsBU(coins []int, n int, val int) int { 53 | minCoins := make([]int, val+1) 54 | for i := range minCoins { 55 | minCoins[i] = math.MaxInt32 56 | } 57 | minCoins[0] = 0 58 | for i := 1; i <= val; i++ { 59 | for j := 0; j < n; j++ { 60 | if coins[j] <= i { 61 | if minCoins[i-coins[j]] != math.MaxInt32 { 62 | minCoins[i] = min(minCoins[i], minCoins[i-coins[j]]+1) 63 | } 64 | } 65 | } 66 | } 67 | if minCoins[val] != math.MaxInt32 { 68 | return minCoins[val] 69 | } 70 | return -1 71 | } 72 | 73 | func MinCoinsBU2(coins []int, n int, val int) int { 74 | minCoins := make([]int, val+1) 75 | coinUsed := make([]int, val+1) 76 | for i := range minCoins { 77 | minCoins[i] = math.MaxInt32 78 | } 79 | minCoins[0] = 0 80 | for i := 1; i <= val; i++ { 81 | for j := 0; j < n; j++ { 82 | if coins[j] <= i { 83 | if minCoins[i-coins[j]] != math.MaxInt32 { 84 | minCoins[i] = min(minCoins[i], minCoins[i-coins[j]]+1) 85 | coinUsed[i] = coins[j] 86 | } 87 | } 88 | } 89 | } 90 | if minCoins[val] == math.MaxInt32 { 91 | return -1 92 | } 93 | 94 | printCoins(coinUsed, val) 95 | return minCoins[val] 96 | } 97 | 98 | func printCoinsUtil(coinUsed []int, val int) string { 99 | if val > 0 { 100 | ret := printCoinsUtil(coinUsed, val-coinUsed[val]) 101 | return ret + strconv.Itoa(coinUsed[val]) + " " 102 | } 103 | return "" 104 | } 105 | 106 | func printCoins(coinUsed []int, val int) { 107 | ret := printCoinsUtil(coinUsed, val) 108 | fmt.Println("Coins are:", ret) 109 | } 110 | 111 | func MinCoinsTD(coins []int, n int, val int) int { 112 | minCoins := make([]int, val+1) 113 | for i := range minCoins { 114 | minCoins[i] = math.MaxInt32 115 | } 116 | return MinCoinsTDUtil(minCoins, coins, val) 117 | } 118 | 119 | func MinCoinsTDUtil(minCoins []int, coins []int, val int) int { 120 | // Base Case 121 | if val == 0 { 122 | return 0 123 | } 124 | if minCoins[val] != math.MaxInt32 { 125 | return minCoins[val] 126 | } 127 | 128 | // Recursion 129 | for i := 0; i < len(coins); i++ { 130 | // check validity of a sub-problem 131 | if coins[i] <= val { 132 | subCount := MinCoinsTDUtil(minCoins, coins, val-coins[i]) 133 | if subCount != math.MaxInt32 { 134 | minCoins[val] = min(minCoins[val], subCount+1) 135 | } 136 | } 137 | } 138 | return minCoins[val] 139 | } 140 | 141 | func min(a, b int) int { 142 | if a < b { 143 | return a 144 | } 145 | return b 146 | } 147 | 148 | func main() { 149 | coins := []int{5, 6} 150 | value := 16 151 | n := len(coins) 152 | fmt.Println("Count is:", MinCoins(coins, n, value)) 153 | fmt.Println("Count is:", MinCoins2(coins, n, value)) 154 | fmt.Println("Count is:", MinCoinsBU(coins, n, value)) 155 | fmt.Println("Count is:", MinCoinsBU2(coins, n, value)) 156 | fmt.Println("Count is:", MinCoinsTD(coins, n, value)) 157 | } 158 | 159 | /* 160 | Count is: -1 161 | Count is: 3 162 | Count is: 3 163 | Coins are: 5 5 6 164 | Count is: 3 165 | Count is: 3 166 | */ 167 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/DiceThrow.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func FindWays(n, m, V int) int { 6 | dp := make([][]int, n+1) 7 | for i := range dp { 8 | dp[i] = make([]int, V+1) 9 | } 10 | 11 | // Table entries for only one dice. 12 | for j := 1; j <= m && j <= V; j++ { 13 | dp[1][j] = 1 14 | } 15 | 16 | // i is the number of dice, j is the value, k is the value of the dice. 17 | for i := 2; i <= n; i++ { 18 | for j := 1; j <= V; j++ { 19 | for k := 1; k <= j && k <= m; k++ { 20 | dp[i][j] += dp[i-1][j-k] 21 | } 22 | } 23 | } 24 | return dp[n][V] 25 | } 26 | 27 | func main() { 28 | fmt.Println(FindWays(3, 6, 6)) 29 | } 30 | 31 | /* 32 | 10 33 | */ 34 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/EditDist.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func min(a, b, c int) int { 6 | // Find the minimum of three numbers. 7 | minVal := a 8 | if b < minVal { 9 | minVal = b 10 | } 11 | if c < minVal { 12 | minVal = c 13 | } 14 | return minVal 15 | } 16 | 17 | func EditDist(str1, str2 string) int { 18 | m := len(str1) 19 | n := len(str2) 20 | return editDistUtil(str1, str2, m, n) 21 | } 22 | 23 | func editDistUtil(str1, str2 string, m, n int) int { 24 | // If any one string is empty, then empty the other string. 25 | if m == 0 || n == 0 { 26 | return m + n 27 | } 28 | 29 | // If last characters of both strings are the same, ignore the last characters. 30 | if str1[m-1] == str2[n-1] { 31 | return editDistUtil(str1, str2, m-1, n-1) 32 | } 33 | 34 | // If the last characters are not the same, consider all three operations: 35 | // Insert last char of the second string into the first. 36 | // Remove the last char of the first string. 37 | // Replace the last char of the first string with the second. 38 | return 1 + min( 39 | editDistUtil(str1, str2, m, n-1), // Insert 40 | editDistUtil(str1, str2, m-1, n), // Remove 41 | editDistUtil(str1, str2, m-1, n-1), // Replace 42 | ) 43 | } 44 | 45 | func EditDistDP(str1, str2 string) int { 46 | m := len(str1) 47 | n := len(str2) 48 | dp := make([][]int, m+1) 49 | for i := range dp { 50 | dp[i] = make([]int, n+1) 51 | } 52 | 53 | // Fill dp[][] in a bottom-up manner. 54 | for i := 0; i <= m; i++ { 55 | for j := 0; j <= n; j++ { 56 | if i == 0 || j == 0 { 57 | // If any one string is empty, then empty the other string. 58 | dp[i][j] = i + j 59 | } else if str1[i-1] == str2[j-1] { 60 | // If last characters of both strings are the same, ignore the last characters. 61 | dp[i][j] = dp[i-1][j-1] 62 | } else { 63 | // If the last characters are not the same, consider all three operations: 64 | // Insert the last char of the second string into the first. 65 | // Remove the last char of the first string. 66 | // Replace the last char of the first string with the second. 67 | dp[i][j] = 1 + min( 68 | dp[i][j-1], // Insert 69 | dp[i-1][j], // Remove 70 | dp[i-1][j-1], // Replace 71 | ) 72 | } 73 | } 74 | } 75 | return dp[m][n] 76 | } 77 | 78 | func main() { 79 | str1 := "sunday" 80 | str2 := "saturday" 81 | fmt.Println(EditDist(str1, str2)) 82 | fmt.Println(EditDistDP(str1, str2)) 83 | } 84 | 85 | /* 86 | 3 87 | 3 88 | */ 89 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/Fibo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func Fibonacci(n int) int { 6 | if n < 2 { 7 | return n 8 | } 9 | return Fibonacci(n-1) + Fibonacci(n-2) 10 | } 11 | 12 | func FibonacciBU2(n int) int { 13 | if n < 2 { 14 | return n 15 | } 16 | 17 | first, second := 0, 1 18 | for i := 2; i <= n; i++ { 19 | first, second = second, first+second 20 | } 21 | return second 22 | } 23 | 24 | func FibonacciBU(n int) int { 25 | if n < 2 { 26 | return n 27 | } 28 | 29 | dp := make([]int, n+1) 30 | dp[0] = 0 31 | dp[1] = 1 32 | 33 | for i := 2; i <= n; i++ { 34 | dp[i] = dp[i-2] + dp[i-1] 35 | } 36 | 37 | return dp[n] 38 | } 39 | 40 | func FibonacciTD(n int) int { 41 | dp := make([]int, n+1) 42 | return fibonacciTDUtil(n, dp) 43 | } 44 | 45 | func fibonacciTDUtil(n int, dp []int) int { 46 | if n < 2 { 47 | dp[n] = n 48 | return n 49 | } 50 | 51 | if dp[n] != 0 { 52 | return dp[n] 53 | } 54 | 55 | dp[n] = fibonacciTDUtil(n-1, dp) + fibonacciTDUtil(n-2, dp) 56 | return dp[n] 57 | } 58 | 59 | func main() { 60 | fmt.Println(Fibonacci(10)) 61 | fmt.Println(FibonacciBU(10)) 62 | fmt.Println(FibonacciBU2(10)) 63 | fmt.Println(FibonacciTD(10)) 64 | } 65 | 66 | /* 67 | 55 68 | 55 69 | 55 70 | 55 71 | */ 72 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/FloydWarshall.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | var INF = math.MaxInt32 9 | 10 | func FloydWarshall(graph [][]int, V int) { 11 | dist := make([][]int, V) 12 | for i := range dist { 13 | dist[i] = make([]int, V) 14 | copy(dist[i], graph[i]) 15 | } 16 | 17 | // Pick intermediate vertices. 18 | for k := 0; k < V; k++ { 19 | // Pick source vertices one by one. 20 | for i := 0; i < V; i++ { 21 | // Pick destination vertices. 22 | for j := 0; j < V; j++ { 23 | // If we have a shorter path from i to j via k, then update dist[i][j]. 24 | if dist[i][k] != INF && dist[k][j] != INF && dist[i][k]+dist[k][j] < dist[i][j] { 25 | dist[i][j] = dist[i][k] + dist[k][j] 26 | } 27 | } 28 | } 29 | } 30 | // Print the shortest distance matrix. 31 | printSolution(dist, V) 32 | } 33 | 34 | func printSolution(dist [][]int, V int) { 35 | for i := 0; i < V; i++ { 36 | for j := 0; j < V; j++ { 37 | if dist[i][j] == INF { 38 | fmt.Print("INF ") 39 | } else { 40 | fmt.Print(dist[i][j], " ") 41 | } 42 | } 43 | fmt.Println() 44 | } 45 | } 46 | 47 | func main() { 48 | graph := [][]int{ 49 | {0, 2, 4, INF, INF, INF, INF}, 50 | {2, 0, 4, 1, INF, INF, INF}, 51 | {4, 4, 0, 2, 8, 4, INF}, 52 | {INF, 1, 2, 0, 3, INF, 6}, 53 | {INF, INF, 6, 4, 0, 3, 1}, 54 | {INF, INF, 4, INF, 4, 0, 2}, 55 | {INF, INF, INF, 4, 2, 3, 0}, 56 | } 57 | FloydWarshall(graph, 7) 58 | } 59 | 60 | /* 61 | 0 2 4 3 6 8 7 62 | 2 0 3 1 4 7 5 63 | 4 3 0 2 5 4 6 64 | 3 1 2 0 3 6 4 65 | 7 5 6 4 0 3 1 66 | 8 7 4 6 4 0 2 67 | 7 5 6 4 2 3 0 68 | */ 69 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/GridMinCost.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func MinCost(cost [][]int, m int, n int) int { 6 | if m == 0 || n == 0 { 7 | return 99999 8 | } 9 | if m == 1 && n == 1 { 10 | return cost[0][0] 11 | } 12 | return cost[m-1][n-1] + min(MinCost(cost, m-1, n-1), MinCost(cost, m-1, n), MinCost(cost, m, n-1)) 13 | } 14 | 15 | func MinCostBU(cost [][]int, m int, n int) int { 16 | tc := make([][]int, m) 17 | for i := range tc { 18 | tc[i] = make([]int, n) 19 | } 20 | tc[0][0] = cost[0][0] 21 | 22 | // Initialize first column. 23 | for i := 1; i < m; i++ { 24 | tc[i][0] = tc[i-1][0] + cost[i][0] 25 | } 26 | 27 | // Initialize first row. 28 | for j := 1; j < n; j++ { 29 | tc[0][j] = tc[0][j-1] + cost[0][j] 30 | } 31 | 32 | for i := 1; i < m; i++ { 33 | for j := 1; j < n; j++ { 34 | tc[i][j] = cost[i][j] + min(tc[i-1][j-1], tc[i-1][j], tc[i][j-1]) 35 | } 36 | } 37 | return tc[m-1][n-1] 38 | } 39 | 40 | func min(a, b, c int) int { 41 | minVal := a 42 | if b < a { 43 | minVal = b 44 | } 45 | if c < minVal { 46 | minVal = c 47 | } 48 | return minVal 49 | } 50 | 51 | func main() { 52 | cost := [][]int{{1, 3, 4}, {4, 7, 5}, {1, 5, 3}} 53 | fmt.Println(MinCost(cost, 3, 3)) 54 | fmt.Println(MinCostBU(cost, 3, 3)) 55 | } 56 | 57 | /* 58 | 11 59 | 11 60 | */ 61 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/GridUniqueWays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Diagonal movement allowed. 6 | func Unique3Ways(m int, n int) int { 7 | dp := make([][]int, m) 8 | for i := range dp { 9 | dp[i] = make([]int, n) 10 | } 11 | dp[0][0] = 1 12 | 13 | // Initialize first column. 14 | for i := 1; i < m; i++ { 15 | dp[i][0] = dp[i-1][0] 16 | } 17 | 18 | // Initialize first row. 19 | for j := 1; j < n; j++ { 20 | dp[0][j] = dp[0][j-1] 21 | } 22 | 23 | for i := 1; i < m; i++ { 24 | for j := 1; j < n; j++ { 25 | dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + dp[i][j-1] 26 | } 27 | } 28 | 29 | return dp[m-1][n-1] 30 | } 31 | 32 | func UniqueWays(m int, n int) int { 33 | dp := make([][]int, m) 34 | for i := range dp { 35 | dp[i] = make([]int, n) 36 | } 37 | dp[0][0] = 1 38 | 39 | // Initialize first column. 40 | for i := 1; i < m; i++ { 41 | dp[i][0] = dp[i-1][0] 42 | } 43 | 44 | // Initialize first row. 45 | for j := 1; j < n; j++ { 46 | dp[0][j] = dp[0][j-1] 47 | } 48 | 49 | for i := 1; i < m; i++ { 50 | for j := 1; j < n; j++ { 51 | dp[i][j] = dp[i-1][j] + dp[i][j-1] 52 | } 53 | } 54 | 55 | return dp[m-1][n-1] 56 | } 57 | 58 | func main() { 59 | fmt.Println(UniqueWays(3, 3)) 60 | fmt.Println(Unique3Ways(3, 3)) 61 | } 62 | 63 | /* 64 | 6 65 | 13 66 | */ 67 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/HouseRobber.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func MaxRobbery(house []int) int { 9 | n := len(house) 10 | dp := make([]int, n) 11 | dp[0] = house[0] 12 | dp[1] = house[1] 13 | dp[2] = dp[0] + house[2] 14 | 15 | for i := 3; i < n; i++ { 16 | dp[i] = int(math.Max(float64(dp[i-2]), float64(dp[i-3]))) + house[i] 17 | } 18 | 19 | return int(math.Max(float64(dp[n-1]), float64(dp[n-2]))) 20 | } 21 | 22 | func MaxRobbery2(house []int) int { 23 | n := len(house) 24 | dp := make([][]int, n) 25 | for i := range dp { 26 | dp[i] = make([]int, 2) 27 | } 28 | 29 | dp[0][1] = house[0] 30 | dp[0][0] = 0 31 | 32 | for i := 1; i < n; i++ { 33 | dp[i][1] = int(math.Max(float64(dp[i-1][0]+house[i]), float64(dp[i-1][1]))) 34 | dp[i][0] = dp[i-1][1] 35 | } 36 | 37 | return int(math.Max(float64(dp[n-1][1]), float64(dp[n-1][0]))) 38 | } 39 | 40 | func main() { 41 | arr := []int{10, 12, 9, 23, 25, 55, 49, 70} 42 | fmt.Println("Total cash:", MaxRobbery(arr)) 43 | fmt.Println("Total cash:", MaxRobbery2(arr)) 44 | } 45 | 46 | /* 47 | Total cash: 160 48 | Total cash: 160 49 | */ 50 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/JobScheduling.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Job struct { 9 | start int 10 | stop int 11 | value int 12 | } 13 | 14 | func NewJob(i1, i2, i3 int) *Job { 15 | j := new(Job) 16 | j.start = i1 17 | j.stop = i2 18 | j.value = i3 19 | return j 20 | } 21 | 22 | // MaxValueJobs calculates the maximum value of jobs that can be performed. 23 | // It uses a recursive approach. 24 | func MaxValueJobs(s []int, f []int, v []int, n int) int { 25 | act := make([]*Job, n) 26 | for i := 0; i < n; i++ { 27 | act[i] = NewJob(s[i], f[i], v[i]) 28 | } 29 | 30 | // Sort the jobs according to finish time. 31 | sort.Slice(act, func(i, j int) bool { 32 | return act[i].stop < act[j].stop 33 | }) 34 | 35 | return maxValueJobUtil(act, n) 36 | } 37 | 38 | func maxValueJobUtil(arr []*Job, n int) int { 39 | // Base case: Only one job remaining. 40 | if n == 1 { 41 | return arr[0].value 42 | } 43 | 44 | // Find the maximum value when the current job is included. 45 | incl := arr[n-1].value 46 | for j := n - 1; j >= 0; j-- { 47 | if arr[j].stop <= arr[n-1].start { 48 | incl += maxValueJobUtil(arr, j+1) 49 | break 50 | } 51 | } 52 | 53 | // Find the maximum value when the current job is excluded. 54 | excl := maxValueJobUtil(arr, n-1) 55 | 56 | return max(incl, excl) 57 | } 58 | 59 | // MaxValueJobsTD calculates the maximum value of jobs that can be performed. 60 | // It uses top-down memoization (dynamic programming) to avoid redundant calculations. 61 | func MaxValueJobsTD(s []int, f []int, v []int, n int) int { 62 | act := make([]*Job, n) 63 | for i := 0; i < n; i++ { 64 | act[i] = NewJob(s[i], f[i], v[i]) 65 | } 66 | 67 | // Sort the jobs according to finish time. 68 | sort.Slice(act, func(i, j int) bool { 69 | return act[i].stop < act[j].stop 70 | }) 71 | 72 | dp := make([]int, n) 73 | 74 | return maxValueJobUtilTD(dp, act, n) 75 | } 76 | 77 | func maxValueJobUtilTD(dp []int, arr []*Job, n int) int { 78 | if n == 0 { 79 | return 0 80 | } 81 | 82 | // Check if the value has already been computed and stored in the dp table. 83 | if dp[n-1] != 0 { 84 | return dp[n-1] 85 | } 86 | 87 | // Find the maximum value when the current job is included. 88 | incl := arr[n-1].value 89 | for j := n - 2; j >= 0; j-- { 90 | if arr[j].stop <= arr[n-1].start { 91 | incl += maxValueJobUtilTD(dp, arr, j+1) 92 | break 93 | } 94 | } 95 | 96 | // Find the maximum value when the current job is excluded. 97 | excl := maxValueJobUtilTD(dp, arr, n-1) 98 | 99 | // Store the computed value in the dp table for future use. 100 | dp[n-1] = max(incl, excl) 101 | 102 | return dp[n-1] 103 | } 104 | 105 | // MaxValueJobsBU calculates the maximum value of jobs that can be performed. 106 | // It uses bottom-up dynamic programming to avoid recursion. 107 | func MaxValueJobsBU(s []int, f []int, v []int, n int) int { 108 | act := make([]*Job, n) 109 | for i := 0; i < n; i++ { 110 | act[i] = NewJob(s[i], f[i], v[i]) 111 | } 112 | 113 | // Sort the jobs according to finish time. 114 | sort.Slice(act, func(i, j int) bool { 115 | return act[i].stop < act[j].stop 116 | }) 117 | 118 | dp := make([]int, n) 119 | dp[0] = act[0].value 120 | 121 | for i := 1; i < n; i++ { 122 | incl := act[i].value 123 | for j := i - 1; j >= 0; j-- { 124 | if act[j].stop <= act[i].start { 125 | incl += dp[j] 126 | break 127 | } 128 | } 129 | dp[i] = max(incl, dp[i-1]) 130 | } 131 | 132 | return dp[n-1] 133 | } 134 | 135 | func max(i, j int) int { 136 | if i > j { 137 | return i 138 | } 139 | return j 140 | } 141 | 142 | func main() { 143 | start := []int{1, 5, 0, 3, 5, 6, 8} 144 | finish := []int{2, 6, 5, 4, 9, 7, 9} 145 | value := []int{2, 2, 4, 3, 10, 2, 8} 146 | n := len(start) 147 | 148 | fmt.Println(MaxValueJobs(start, finish, value, n)) 149 | fmt.Println(MaxValueJobsTD(start, finish, value, n)) 150 | fmt.Println(MaxValueJobsBU(start, finish, value, n)) 151 | } 152 | 153 | /* 154 | Output: 155 | 17 156 | 17 157 | 17 158 | */ 159 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/Knapsack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type Item struct { 9 | weight int 10 | cost int 11 | } 12 | 13 | func NewItem(weight, cost int) *Item { 14 | return &Item{ 15 | weight: weight, 16 | cost: cost, 17 | } 18 | } 19 | 20 | func KS01UnboundedBU(items []*Item, capacity int) int { 21 | n := len(items) 22 | dp := make([]int, capacity+1) 23 | 24 | for w := 1; w <= capacity; w++ { 25 | for i := 0; i < n; i++ { 26 | itemWeight := items[i].weight 27 | itemCost := items[i].cost 28 | 29 | if itemWeight <= w { 30 | dp[w] = max(dp[w], dp[w-itemWeight]+itemCost) 31 | } 32 | } 33 | } 34 | 35 | return dp[capacity] 36 | } 37 | 38 | func GetMaxCost01(items []*Item, capacity int) int { 39 | n := len(items) 40 | return getMaxCost01Util(items, n, capacity) 41 | } 42 | 43 | func getMaxCost01Util(items []*Item, n, capacity int) int { 44 | // Base case 45 | if n == 0 || capacity == 0 { 46 | return 0 47 | } 48 | 49 | // Return the maximum of two cases: 50 | // (1) nth item is included 51 | // (2) nth item is not included 52 | first := 0 53 | itemWeight := items[n-1].weight 54 | itemCost := items[n-1].cost 55 | 56 | if itemWeight <= capacity { 57 | first = itemCost + getMaxCost01Util(items, n-1, capacity-itemWeight) 58 | } 59 | 60 | second := getMaxCost01Util(items, n-1, capacity) 61 | 62 | return max(first, second) 63 | } 64 | 65 | func GetMaxCost01TD(items []*Item, capacity int) int { 66 | n := len(items) 67 | dp := make([][]int, capacity+1) 68 | for i := range dp { 69 | dp[i] = make([]int, n) 70 | } 71 | 72 | return getMaxCost01TDUtil(dp, items, n, capacity) 73 | } 74 | 75 | func getMaxCost01TDUtil(dp [][]int, items []*Item, n, capacity int) int { 76 | if capacity == 0 || n == 0 { 77 | return 0 78 | } 79 | 80 | if dp[capacity][n-1] != 0 { 81 | return dp[capacity][n-1] 82 | } 83 | 84 | // Their are two cases: 85 | // (1) ith item is included 86 | // (2) ith item is not included 87 | first := 0 88 | itemWeight := items[n-1].weight 89 | itemCost := items[n-1].cost 90 | 91 | if itemWeight <= capacity { 92 | first = itemCost + getMaxCost01TDUtil(dp, items, n-1, capacity-itemWeight) 93 | } 94 | 95 | second := getMaxCost01TDUtil(dp, items, n-1, capacity) 96 | dp[capacity][n-1] = max(first, second) 97 | 98 | return dp[capacity][n-1] 99 | } 100 | 101 | func GetMaxCost01BU(items []*Item, capacity int) int { 102 | n := len(items) 103 | dp := make([][]int, capacity+1) 104 | for i := range dp { 105 | dp[i] = make([]int, n+1) 106 | } 107 | 108 | // Build table dp[][] in bottom up approach. 109 | // Weights considered against capacity. 110 | for w := 1; w <= capacity; w++ { 111 | for i := 1; i <= n; i++ { 112 | itemWeight := items[i-1].weight 113 | itemCost := items[i-1].cost 114 | 115 | // Their are two cases: 116 | // (1) ith item is included 117 | // (2) ith item is not included 118 | first := 0 119 | if itemWeight <= w { 120 | first = dp[w-itemWeight][i-1] + itemCost 121 | } 122 | 123 | second := dp[w][i-1] 124 | dp[w][i] = max(first, second) 125 | } 126 | } 127 | printSelectedItems(dp, items, n, capacity) 128 | // Number of weights considered and final capacity. 129 | return dp[capacity][n] 130 | } 131 | 132 | func max(a, b int) int { 133 | if a > b { 134 | return a 135 | } 136 | return b 137 | } 138 | 139 | func printSelectedItems(dp [][]int, items []*Item, n, capacity int) { 140 | totalCost := dp[capacity][n] 141 | output := "" 142 | 143 | for i := n - 1; i > 0; i-- { 144 | if totalCost != dp[capacity][i-1] { 145 | itemWeight := items[i].weight 146 | itemCost := items[i].cost 147 | 148 | output += " (wt:" + strconv.Itoa(itemWeight) + ", cost:" + strconv.Itoa(itemCost) + ")" 149 | capacity -= itemWeight 150 | totalCost -= itemCost 151 | } 152 | } 153 | 154 | fmt.Println("Selected items are:" + output) 155 | } 156 | 157 | func main() { 158 | items := []*Item{ 159 | NewItem(10, 60), 160 | NewItem(40, 40), 161 | NewItem(20, 90), 162 | NewItem(30, 120), 163 | } 164 | capacity := 50 165 | 166 | maxCost := KS01UnboundedBU(items, capacity) 167 | fmt.Println("Maximum cost obtained =", maxCost) 168 | 169 | maxCost = GetMaxCost01(items, capacity) 170 | fmt.Println("Maximum cost obtained =", maxCost) 171 | 172 | maxCost = GetMaxCost01BU(items, capacity) 173 | fmt.Println("Maximum cost obtained =", maxCost) 174 | 175 | maxCost = GetMaxCost01TD(items, capacity) 176 | fmt.Println("Maximum cost obtained =", maxCost) 177 | } 178 | 179 | /*Maximum cost obtained = 300 180 | Maximum cost obtained = 210 181 | Selected items are: (wt:30, cost:120) (wt:20, cost:90) 182 | Maximum cost obtained = 210 183 | Maximum cost obtained = 210 184 | */ 185 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/LargestBitonicSubseq.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func max(i, j int) int { 6 | if i > j { 7 | return i 8 | } 9 | return j 10 | } 11 | 12 | func LargestBitonicSubseq(arr []int) int { 13 | n := len(arr) 14 | lis := make([]int, n) 15 | // Initialize LIS values for all indexes as 1. 16 | for i := range lis { 17 | lis[i] = 1 18 | } 19 | 20 | lds := make([]int, n) 21 | // Initialize LDS values for all indexes as 1. 22 | for i := range lds { 23 | lds[i] = 1 24 | } 25 | 26 | // Populating LIS values in bottom-up manner. 27 | for i := 0; i < n; i++ { 28 | for j := 0; j < i; j++ { 29 | if arr[j] < arr[i] && lis[i] < lis[j]+1 { 30 | lis[i] = lis[j] + 1 31 | } 32 | } 33 | } 34 | 35 | // Populating LDS values in bottom-up manner. 36 | for i := n - 1; i > 0; i-- { 37 | for j := n - 1; j > i; j-- { 38 | if arr[j] < arr[i] && lds[i] < lds[j]+1 { 39 | lds[i] = lds[j] + 1 40 | } 41 | } 42 | } 43 | 44 | maxVal := 0 45 | for i := 0; i < n; i++ { 46 | if maxVal < lis[i]+lds[i]-1 { 47 | maxVal = lis[i] + lds[i] - 1 48 | } 49 | } 50 | 51 | return maxVal 52 | } 53 | 54 | func main() { 55 | arr := []int{1, 6, 3, 11, 1, 9, 5, 12, 3, 14, 6, 17, 3, 19, 2, 19} 56 | fmt.Println("Length of LBS is", LargestBitonicSubseq(arr)) 57 | } 58 | 59 | /* 60 | Length of LBS is 8 61 | */ 62 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/LargestIncreasingSubseq.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func LargestIncreasingSubseq(arr []int) int { 6 | n := len(arr) 7 | lis := make([]int, n) 8 | maxVal := 0 9 | 10 | // Populating LIS values in bottom-up manner. 11 | for i := 0; i < n; i++ { 12 | lis[i] = 1 // Initialize LIS values for all indexes as 1. 13 | for j := 0; j < i; j++ { 14 | if arr[j] < arr[i] && lis[i] < lis[j]+1 { 15 | lis[i] = lis[j] + 1 16 | } 17 | } 18 | if maxVal < lis[i] { 19 | maxVal = lis[i] 20 | } 21 | } 22 | 23 | return maxVal 24 | } 25 | 26 | func main() { 27 | arr := []int{10, 12, 9, 23, 25, 55, 49, 70} 28 | fmt.Println("Length of lis is", LargestIncreasingSubseq(arr)) 29 | } 30 | 31 | /* 32 | Length of lis is 6 33 | */ 34 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/LargestPalindromicSubsequence.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func max(i, j int) int { 6 | if i > j { 7 | return i 8 | } 9 | return j 10 | } 11 | 12 | func LargestPalindromicSubsequence(str string) int { 13 | n := len(str) 14 | dp := make([][]int, n) 15 | for i := range dp { 16 | dp[i] = make([]int, n) 17 | } 18 | 19 | // each char is itself palindromic with length 1 20 | for i := 0; i < n; i++ { 21 | dp[i][i] = 1 22 | } 23 | 24 | for l := 1; l < n; l++ { 25 | for i, j := 0, l; j < n; i, j = i+1, j+1 { 26 | if str[i] == str[j] { 27 | dp[i][j] = dp[i+1][j-1] + 2 28 | } else { 29 | dp[i][j] = max(dp[i+1][j], dp[i][j-1]) 30 | } 31 | } 32 | } 33 | return dp[0][n-1] 34 | } 35 | 36 | func main() { 37 | str := "ABCAUCBCxxCBA" 38 | fmt.Println("Max Palindromic Subsequence length:", LargestPalindromicSubsequence(str)) 39 | } 40 | 41 | /* 42 | Max Palindromic Subsequence length: 9 43 | */ 44 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/LargestPalindromicSubstr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func LargestPalindromicSubstr(str string) int { 6 | n := len(str) 7 | dp := make([][]int, n) 8 | for i := range dp { 9 | dp[i] = make([]int, n) 10 | } 11 | 12 | for i := 0; i < n; i++ { 13 | dp[i][i] = 1 14 | } 15 | 16 | maxVal := 1 17 | start := 0 18 | for l := 1; l < n; l++ { 19 | for i, j := 0, l; j < n; i, j = i+1, j+1 { 20 | if str[i] == str[j] && dp[i+1][j-1] == j-i-1 { 21 | dp[i][j] = dp[i+1][j-1] + 2 22 | if dp[i][j] > maxVal { 23 | maxVal = dp[i][j] // Keeping track of max length and 24 | start = i // starting position of sub-string. 25 | } 26 | } else { 27 | dp[i][j] = 0 28 | } 29 | } 30 | } 31 | fmt.Println("Max Length Palindromic Substrings:", str[start:start+maxVal]) 32 | return maxVal 33 | } 34 | 35 | func main() { 36 | str := "ABCAUCBCxxCBA" 37 | fmt.Println("Max Palindromic Substrings len:", LargestPalindromicSubstr(str)) 38 | } 39 | 40 | /* 41 | Max Length Palindromic Substrings: BCxxCB 42 | Max Palindromic Substrings len: 6 43 | */ 44 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/LongestCommonSubseq.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func LongestCommonSubseq(X string, Y string) int { 6 | m := len(X) 7 | n := len(Y) 8 | dp := make([][]int, m+1) // Dynamic programming array. 9 | p := make([][]int, m+1) // For printing the substring. 10 | 11 | for i := range dp { 12 | dp[i] = make([]int, n+1) 13 | p[i] = make([]int, n+1) 14 | } 15 | 16 | // Fill dp array in bottom up fashion. 17 | for i := 1; i <= m; i++ { 18 | for j := 1; j <= n; j++ { 19 | if X[i-1] == Y[j-1] { 20 | dp[i][j] = dp[i-1][j-1] + 1 21 | p[i][j] = 0 22 | } else { 23 | if dp[i-1][j] > dp[i][j-1] { 24 | dp[i][j] = dp[i-1][j] 25 | p[i][j] = 1 26 | } else { 27 | dp[i][j] = dp[i][j-1] 28 | p[i][j] = 2 29 | } 30 | } 31 | } 32 | } 33 | printLCS(p, X, m, n) 34 | return dp[m][n] 35 | } 36 | 37 | func printLCS(p [][]int, X string, i int, j int) { 38 | fmt.Print("LongestCommonSubseq: ") 39 | printLCSUtil(p, X, i, j) 40 | fmt.Println() 41 | } 42 | 43 | func printLCSUtil(p [][]int, X string, i int, j int) { 44 | if i == 0 || j == 0 { 45 | return 46 | } 47 | if p[i][j] == 0 { 48 | printLCSUtil(p, X, i-1, j-1) 49 | fmt.Print(string(X[i-1])) 50 | } else if p[i][j] == 1 { 51 | printLCSUtil(p, X, i-1, j) 52 | } else { 53 | printLCSUtil(p, X, i, j-1) 54 | } 55 | } 56 | 57 | func main() { 58 | X := "carpenter" 59 | Y := "sharpener" 60 | result := LongestCommonSubseq(X, Y) 61 | fmt.Println("LongestCommonSubseq length:", result) 62 | } 63 | 64 | /* 65 | LongestCommonSubseq: arpener 66 | LongestCommonSubseq length: 7 67 | */ 68 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/MatrixCM.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "strconv" 7 | ) 8 | 9 | func MatrixChainMulBruteForce(p []int, n int) int { 10 | i := 1 11 | j := n - 1 12 | return matrixChainMulBruteForceUtil(p, i, j) 13 | } 14 | 15 | func matrixChainMulBruteForceUtil(p []int, i int, j int) int { 16 | if i == j { 17 | return 0 18 | } 19 | min := math.MaxInt32 20 | 21 | // Place parentheses at different places between 22 | // the first and last matrix, recursively calculate 23 | // the count of multiplications for each parenthesis 24 | // placement and return the minimum count 25 | for k := i; k < j; k++ { 26 | count := matrixChainMulBruteForceUtil(p, i, k) + 27 | matrixChainMulBruteForceUtil(p, k+1, j) + p[i-1]*p[k]*p[j] 28 | if count < min { 29 | min = count 30 | } 31 | } 32 | return min // Return minimum count 33 | } 34 | 35 | func MatrixChainMulTD(p []int, n int) int { 36 | dp := make([][]int, n) 37 | for i := range dp { 38 | dp[i] = make([]int, n) 39 | for j := range dp[i] { 40 | dp[i][j] = math.MaxInt32 41 | } 42 | } 43 | return matrixChainMulTDUtil(dp, p, 1, n-1) 44 | } 45 | 46 | func matrixChainMulTDUtil(dp [][]int, p []int, i int, j int) int { 47 | // Base Case 48 | if i == j { 49 | return 0 50 | } 51 | if dp[i][j] != math.MaxInt32 { 52 | return dp[i][j] 53 | } 54 | 55 | // Recursion 56 | for k := i; k < j; k++ { 57 | dp[i][j] = min(dp[i][j], matrixChainMulTDUtil(dp, p, i, k)+ 58 | matrixChainMulTDUtil(dp, p, k+1, j)+p[i-1]*p[k]*p[j]) 59 | } 60 | return dp[i][j] 61 | } 62 | 63 | func MatrixChainMulBU(p []int, n int) int { 64 | dp := make([][]int, n) 65 | for i := range dp { 66 | dp[i] = make([]int, n) 67 | for j := range dp[i] { 68 | dp[i][j] = math.MaxInt32 69 | } 70 | } 71 | 72 | for i := 1; i < n; i++ { 73 | dp[i][i] = 0 74 | } 75 | 76 | for l := 1; l < n; l++ { 77 | for i, j := 1, l; j < n; i, j = i+1, j+1 { 78 | for k := i; k < j; k++ { 79 | dp[i][j] = min(dp[i][j], dp[i][k]+p[i-1]*p[k]*p[j]+dp[k+1][j]) 80 | } 81 | } 82 | } 83 | return dp[1][n-1] 84 | } 85 | 86 | func min(a, b int) int { 87 | if a < b { 88 | return a 89 | } 90 | return b 91 | } 92 | 93 | func MatrixChainMulBU2(p []int, n int) int { 94 | dp := make([][]int, n) 95 | pos := make([][]int, n) 96 | for i := range dp { 97 | dp[i] = make([]int, n) 98 | pos[i] = make([]int, n) 99 | for j := range dp[i] { 100 | dp[i][j] = math.MaxInt32 101 | pos[i][i] = i 102 | } 103 | } 104 | 105 | for i := 1; i < n; i++ { 106 | dp[i][i] = 0 107 | } 108 | 109 | for l := 1; l < n; l++ { 110 | for i, j := 1, l; j < n; i, j = i+1, j+1 { 111 | for k := i; k < j; k++ { 112 | dp[i][j] = min(dp[i][j], dp[i][k]+p[i-1]*p[k]*p[j]+dp[k+1][j]) 113 | pos[i][j] = k 114 | } 115 | } 116 | } 117 | printOptimalParenthesis(n, pos) 118 | return dp[1][n-1] 119 | } 120 | 121 | func printOptPar(n int, pos [][]int, i int, j int) string { 122 | output := "" 123 | if i == j { 124 | output += "M" + strconv.Itoa(pos[i][i]) + " " 125 | } else { 126 | output += "( " 127 | output += printOptPar(n, pos, i, pos[i][j]) 128 | output += printOptPar(n, pos, pos[i][j]+1, j) 129 | output += ") " 130 | } 131 | return output 132 | } 133 | 134 | func printOptimalParenthesis(n int, pos [][]int) { 135 | fmt.Println("Optimal Parenthesis:", printOptPar(n, pos, 1, n-1)) 136 | } 137 | 138 | func main() { 139 | arr := []int{1, 2, 3, 4} 140 | n := len(arr) 141 | fmt.Println("Matrix Chain Multiplication is:", MatrixChainMulBruteForce(arr, n)) 142 | fmt.Println("Matrix Chain Multiplication is:", MatrixChainMulTD(arr, n)) 143 | fmt.Println("Matrix Chain Multiplication is:", MatrixChainMulBU(arr, n)) 144 | fmt.Println("Matrix Chain Multiplication is:", MatrixChainMulBU2(arr, n)) 145 | } 146 | 147 | /* 148 | Matrix Chain Multiplication is: 18 149 | Matrix Chain Multiplication is: 18 150 | Matrix Chain Multiplication is: 18 151 | Optimal Parenthesis: ( ( M1 M2 ) M3 ) 152 | Matrix Chain Multiplication is: 18 153 | */ 154 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/MinCostBinaryTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func min(a, b int) int { 9 | if a < b { 10 | return a 11 | } 12 | return b 13 | } 14 | 15 | func max(a, b int) int { 16 | if a > b { 17 | return a 18 | } 19 | return b 20 | } 21 | 22 | func MinCostBSTTD(arr []int) int { 23 | n := len(arr) 24 | dp := make([][]int, n) 25 | maxVal := make([][]int, n) 26 | 27 | for i := range dp { 28 | dp[i] = make([]int, n) 29 | maxVal[i] = make([]int, n) 30 | for j := range dp[i] { 31 | dp[i][j] = math.MaxInt32 32 | maxVal[i][j] = math.MinInt32 33 | } 34 | } 35 | 36 | for i := 0; i < n; i++ { 37 | maxVal[i][i] = arr[i] 38 | } 39 | return minCostBSTTDUtil(dp, maxVal, 0, n-1, arr) 40 | } 41 | 42 | func minCostBSTTDUtil(dp [][]int, maxVal [][]int, i int, j int, arr []int) int { 43 | if j <= i { 44 | return 0 45 | } 46 | if dp[i][j] != math.MaxInt32 { 47 | return dp[i][j] 48 | } 49 | for k := i; k < j; k++ { 50 | dp[i][j] = min(dp[i][j], 51 | minCostBSTTDUtil(dp, maxVal, i, k, arr)+ 52 | minCostBSTTDUtil(dp, maxVal, k+1, j, arr)+ 53 | findMaxVal(maxVal, i, k)*findMaxVal(maxVal, k+1, j)) 54 | } 55 | return dp[i][j] 56 | } 57 | 58 | func findMaxVal(maxVal [][]int, i int, j int) int { 59 | if maxVal[i][j] != math.MinInt32 { 60 | return maxVal[i][j] 61 | } 62 | for k := i; k < j; k++ { 63 | maxVal[i][j] = max(maxVal[i][j], 64 | max(findMaxVal(maxVal, i, k), findMaxVal(maxVal, k+1, j))) 65 | } 66 | return maxVal[i][j] 67 | } 68 | 69 | func MinCostBSTBU(arr []int) int { 70 | n := len(arr) 71 | dp := make([][]int, n) 72 | maxVal := make([][]int, n) 73 | for i := range dp { 74 | dp[i] = make([]int, n) 75 | maxVal[i] = make([]int, n) 76 | } 77 | for i := 0; i < n; i++ { 78 | maxVal[i][i] = arr[i] 79 | } 80 | 81 | for l := 1; l < n; l++ { // l is the length of the range. 82 | for i, j := 0, l; j < n; i, j = i+1, j+1 { 83 | dp[i][j] = math.MaxInt32 84 | for k := i; k < j; k++ { 85 | dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+maxVal[i][k]*maxVal[k+1][j]) 86 | maxVal[i][j] = max(maxVal[i][k], maxVal[k+1][j]) 87 | } 88 | } 89 | } 90 | return dp[0][n-1] 91 | } 92 | 93 | func main() { 94 | arr := []int{6, 2, 4} 95 | fmt.Println("Total cost:", MinCostBSTTD(arr)) 96 | fmt.Println("Total cost:", MinCostBSTBU(arr)) 97 | } 98 | 99 | /* 100 | Total cost: 32 101 | Total cost: 32 102 | */ 103 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/MinStairCost.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func MinStairCost(cost []int, n int) int { 6 | // base cases 7 | if n == 0 { 8 | return 0 9 | } 10 | if n == 1 { 11 | return cost[0] 12 | } 13 | if n == 2 { 14 | return min(cost[0], cost[1]) 15 | } 16 | dp := make([]int, n) 17 | dp[0] = cost[0] 18 | dp[1] = cost[1] 19 | for i := 2; i < n; i++ { 20 | dp[i] = min(dp[i-1], dp[i-2]) + cost[i] 21 | } 22 | return min(dp[n-2], dp[n-1]) 23 | } 24 | 25 | func min(a, b int) int { 26 | if a < b { 27 | return a 28 | } 29 | return b 30 | } 31 | 32 | func main() { 33 | a := []int{1, 5, 6, 3, 4, 7, 9, 1, 2, 11} 34 | n := len(a) 35 | fmt.Println(MinStairCost(a, n)) 36 | } 37 | 38 | /* 39 | 18 40 | */ 41 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/OptimalBST.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func OptimalBSTCost(keys []int, freq []int) int { 9 | n := len(freq) 10 | return optimalBSTCostUtil(freq, 0, n-1) 11 | } 12 | 13 | func optimalBSTCostUtil(freq []int, i int, j int) int { 14 | if i > j { 15 | return 0 16 | } 17 | if j == i { // one element in this subarray 18 | return freq[i] 19 | } 20 | minVal := math.MaxInt32 21 | for r := i; r <= j; r++ { 22 | minVal = min(minVal, 23 | optimalBSTCostUtil(freq, i, r-1)+ 24 | optimalBSTCostUtil(freq, r+1, j)) 25 | } 26 | return minVal + sumAll(freq, i, j) 27 | } 28 | 29 | func sumAll(freq []int, i int, j int) int { 30 | s := 0 31 | for k := i; k <= j; k++ { 32 | s += freq[k] 33 | } 34 | return s 35 | } 36 | 37 | func OptimalBSTCostTD(keys []int, freq []int) int { 38 | n := len(freq) 39 | cost := make([][]int, n) 40 | for i := range cost { 41 | cost[i] = make([]int, n) 42 | for j := range cost[i] { 43 | cost[i][j] = math.MaxInt32 44 | } 45 | } 46 | 47 | for i := 0; i < n; i++ { 48 | cost[i][i] = freq[i] 49 | } 50 | return optimalBSTCostTDUtil(freq, cost, 0, n-1) 51 | } 52 | 53 | func optimalBSTCostTDUtil(freq []int, cost [][]int, i int, j int) int { 54 | if i > j { 55 | return 0 56 | } 57 | if cost[i][j] != math.MaxInt32 { 58 | return cost[i][j] 59 | } 60 | s := sumAll(freq, i, j) 61 | for r := i; r <= j; r++ { 62 | cost[i][j] = min(cost[i][j], 63 | optimalBSTCostTDUtil(freq, cost, i, r-1)+ 64 | optimalBSTCostTDUtil(freq, cost, r+1, j)+s) 65 | } 66 | return cost[i][j] 67 | } 68 | 69 | func min(a, b int) int { 70 | if a < b { 71 | return a 72 | } 73 | return b 74 | } 75 | 76 | func OptimalBSTCostBU(keys []int, freq []int) int { 77 | n := len(freq) 78 | cost := make([][]int, n) 79 | for i := range cost { 80 | cost[i] = make([]int, n) 81 | for j := range cost[i] { 82 | cost[i][j] = math.MaxInt32 83 | } 84 | } 85 | 86 | for i := 0; i < n; i++ { 87 | cost[i][i] = freq[i] 88 | } 89 | sm := 0 90 | // l is length of range. 91 | for l := 1; l < n; l++ { 92 | for i, j := 0, l; j < n; i, j = i+1, j+1 { 93 | sm = sumAll(freq, i, j) 94 | for r := i; r <= j; r++ { 95 | first, second := 0, 0 96 | if r-1 >= i { 97 | first = cost[i][r-1] 98 | } 99 | if r+1 <= j { 100 | second = cost[r+1][j] 101 | } 102 | cost[i][j] = min(cost[i][j], sm+first+second) 103 | } 104 | } 105 | } 106 | return cost[0][n-1] 107 | } 108 | 109 | func OptimalBSTCostBU2(keys []int, freq []int) int { 110 | n := len(freq) 111 | cost := make([][]int, n) 112 | for i := range cost { 113 | cost[i] = make([]int, n) 114 | for j := range cost[i] { 115 | cost[i][j] = math.MaxInt32 116 | } 117 | } 118 | 119 | sumArr := sumInit(freq, n) 120 | for i := 0; i < n; i++ { 121 | cost[i][i] = freq[i] 122 | } 123 | 124 | sm := 0 125 | // l is length of range. 126 | for l := 1; l < n; l++ { 127 | for i, j := 0, l; j < n; i, j = i+1, j+1 { 128 | sm = sumRange(sumArr, i, j) 129 | for r := i; r <= j; r++ { 130 | first, second := 0, 0 131 | if r-1 >= i { 132 | first = cost[i][r-1] 133 | } 134 | if r+1 <= j { 135 | second = cost[r+1][j] 136 | } 137 | cost[i][j] = min(cost[i][j], sm+first+second) 138 | } 139 | } 140 | } 141 | return cost[0][n-1] 142 | } 143 | 144 | func sumInit(freq []int, n int) []int { 145 | sum := make([]int, n) 146 | sum[0] = freq[0] 147 | for i := 1; i < n; i++ { 148 | sum[i] = sum[i-1] + freq[i] 149 | } 150 | return sum 151 | } 152 | 153 | func sumRange(sum []int, i int, j int) int { 154 | if i == 0 { 155 | return sum[j] 156 | } 157 | return sum[j] - sum[i-1] 158 | } 159 | 160 | func main() { 161 | keys := []int{9, 15, 25} 162 | freq := []int{30, 10, 40} 163 | fmt.Println("OBST cost:", OptimalBSTCost(keys, freq)) 164 | fmt.Println("OBST cost:", OptimalBSTCostTD(keys, freq)) 165 | fmt.Println("OBST cost:", OptimalBSTCostBU(keys, freq)) 166 | fmt.Println("OBST cost:", OptimalBSTCostBU2(keys, freq)) 167 | } 168 | 169 | /* 170 | OBST cost: 130 171 | OBST cost: 130 172 | OBST cost: 130 173 | OBST cost: 130 174 | */ 175 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/StairUniqueWays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func StairUniqueWaysBU(n int) int { 6 | if n <= 2 { 7 | return n 8 | } 9 | first := 1 10 | second := 2 11 | temp := 0 12 | for i := 3; i <= n; i++ { 13 | temp = first + second 14 | first = second 15 | second = temp 16 | } 17 | return temp 18 | } 19 | 20 | func StairUniqueWaysBU2(n int) int { 21 | if n < 2 { 22 | return n 23 | } 24 | ways := make([]int, n) 25 | ways[0] = 1 26 | ways[1] = 2 27 | for i := 2; i < n; i++ { 28 | ways[i] = ways[i-1] + ways[i-2] 29 | } 30 | return ways[n-1] 31 | } 32 | 33 | func main() { 34 | fmt.Println("Unique way to reach top:", StairUniqueWaysBU(4)) 35 | fmt.Println("Unique way to reach top:", StairUniqueWaysBU2(4)) 36 | } 37 | 38 | /* 39 | Unique way to reach top: 5 40 | Unique way to reach top: 5 41 | */ 42 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/StockBuySell.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func StockBuySellMaxProfit(arr []int) int { 6 | buyProfit := -arr[0] // Buy stock profit 7 | sellProfit := 0 // Sell stock profit 8 | n := len(arr) 9 | for i := 1; i < n; i++ { 10 | newBuyProfit := buyProfit 11 | if sellProfit-arr[i] > buyProfit { 12 | newBuyProfit = sellProfit - arr[i] 13 | } 14 | newSellProfit := sellProfit 15 | if buyProfit+arr[i] > sellProfit { 16 | newSellProfit = buyProfit + arr[i] 17 | } 18 | 19 | buyProfit = newBuyProfit 20 | sellProfit = newSellProfit 21 | } 22 | return sellProfit 23 | } 24 | 25 | func StockBuySellMaxProfit2(arr []int) int { 26 | n := len(arr) 27 | dp := make([][]int, n) 28 | for i := range dp { 29 | dp[i] = make([]int, 2) 30 | } 31 | 32 | dp[0][0] = -arr[0] 33 | dp[0][1] = 0 34 | for i := 1; i < n; i++ { 35 | dp[i][0] = dp[i-1][0] 36 | if dp[i-1][1]-arr[i] > dp[i-1][0] { 37 | dp[i][0] = dp[i-1][1] - arr[i] 38 | } 39 | dp[i][1] = dp[i-1][1] 40 | if dp[i-1][0]+arr[i] > dp[i-1][1] { 41 | dp[i][1] = dp[i-1][0] + arr[i] 42 | } 43 | } 44 | return dp[n-1][1] 45 | } 46 | 47 | func StockBuySellMaxProfitTC(arr []int, t int) int { 48 | buyProfit := -arr[0] // Buy stock profit 49 | sellProfit := 0 // Sell stock profit 50 | n := len(arr) 51 | for i := 1; i < n; i++ { 52 | newBuyProfit := buyProfit 53 | if sellProfit-arr[i] > buyProfit { 54 | newBuyProfit = sellProfit - arr[i] 55 | } 56 | newSellProfit := sellProfit 57 | if buyProfit+arr[i]-t > sellProfit { 58 | newSellProfit = buyProfit + arr[i] - t 59 | } 60 | buyProfit = newBuyProfit 61 | sellProfit = newSellProfit 62 | } 63 | return sellProfit 64 | } 65 | 66 | func StockBuySellMaxProfitTC2(arr []int, t int) int { 67 | n := len(arr) 68 | dp := make([][]int, n) 69 | for i := range dp { 70 | dp[i] = make([]int, 2) 71 | } 72 | 73 | dp[0][0] = -arr[0] 74 | dp[0][1] = 0 75 | for i := 1; i < n; i++ { 76 | dp[i][0] = dp[i-1][0] 77 | if dp[i-1][1]-arr[i] > dp[i-1][0] { 78 | dp[i][0] = dp[i-1][1] - arr[i] 79 | } 80 | dp[i][1] = dp[i-1][1] 81 | if dp[i-1][0]+arr[i]-t > dp[i-1][1] { 82 | dp[i][1] = dp[i-1][0] + arr[i] - t 83 | } 84 | } 85 | return dp[n-1][1] 86 | } 87 | 88 | func main() { 89 | arr := []int{10, 12, 9, 23, 25, 55, 49, 70} 90 | fmt.Println("Total profit:", StockBuySellMaxProfit(arr)) 91 | fmt.Println("Total profit:", StockBuySellMaxProfit2(arr)) 92 | fmt.Println("Total profit:", StockBuySellMaxProfitTC(arr, 2)) 93 | fmt.Println("Total profit:", StockBuySellMaxProfitTC2(arr, 2)) 94 | } 95 | 96 | /* 97 | Total profit: 69 98 | Total profit: 69 99 | Total profit: 63 100 | Total profit: 63 101 | */ 102 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/Vacation.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func min(a, b int) int { 6 | if a < b { 7 | return a 8 | } 9 | return b 10 | } 11 | 12 | func max(a, b int) int { 13 | if a > b { 14 | return a 15 | } 16 | return b 17 | } 18 | 19 | // days are must travel days, costs are cost of tickets. 20 | func MinCostTravel(days []int, costs []int) int { 21 | n := len(days) 22 | maxVal := days[n-1] 23 | dp := make([]int, maxVal+1) 24 | j := 0 25 | for i := 1; i <= maxVal; i++ { 26 | if days[j] == i { // That day is definitely traveled. 27 | j++ 28 | dp[i] = dp[i-1] + costs[0] 29 | dp[i] = min(dp[i], dp[max(0, i-7)]+costs[1]) 30 | dp[i] = min(dp[i], dp[max(0, i-30)]+costs[2]) 31 | } else { 32 | dp[i] = dp[i-1] // The day may be ignored. 33 | } 34 | } 35 | return dp[maxVal] 36 | } 37 | 38 | func main() { 39 | days := []int{1, 3, 5, 7, 12, 20, 30} 40 | costs := []int{2, 7, 20} 41 | fmt.Println("Min cost is:", MinCostTravel(days, costs)) 42 | } 43 | 44 | /* 45 | Min cost is: 13 46 | */ 47 | -------------------------------------------------------------------------------- /AlgorithmsChapters/DP/WildCharMatch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(WildCharMatchExp("*llo,?World?", "Hello, World!")) 7 | fmt.Println(WildCharMatchExpDP("*llo,?World?", "Hello, World!")) 8 | } 9 | 10 | func WildCharMatchExp(exp string, str string) bool { 11 | return wildCharMatchExpUtil(exp, str, 0, 0) 12 | } 13 | 14 | func wildCharMatchExpUtil(exp string, str string, m int, n int) bool { 15 | if m == len(exp) && (n == len(str) || exp[m-1] == '*') { 16 | return true 17 | } 18 | if m == len(exp) && n != len(str) || m != len(exp) && n == len(str) { 19 | return false 20 | } 21 | if exp[m] == '?' || exp[m] == str[n] { 22 | return wildCharMatchExpUtil(exp, str, m+1, n+1) 23 | } 24 | if exp[m] == '*' { 25 | return wildCharMatchExpUtil(exp, str, m+1, n) || wildCharMatchExpUtil(exp, str, m, n+1) 26 | } 27 | return false 28 | } 29 | 30 | func WildCharMatchExpDP(exp string, str string) bool { 31 | return wildCharMatchExpUtilDP(exp, str, len(exp), len(str)) 32 | } 33 | 34 | func wildCharMatchExpUtilDP(exp string, str string, m int, n int) bool { 35 | lookup := make([][]bool, m+1) 36 | for i := range lookup { 37 | lookup[i] = make([]bool, n+1) 38 | } 39 | 40 | // empty exp and empty str match. 41 | lookup[0][0] = true 42 | 43 | // 0 row will remain all false. empty exp can't match any str. 44 | // '*' can match with empty string, column 0 update. 45 | for i := 1; i <= m; i++ { 46 | if exp[i-1] == '*' { 47 | lookup[i][0] = lookup[i-1][0] 48 | } else { 49 | break 50 | } 51 | } 52 | 53 | // Fill the table in bottom-up fashion 54 | for i := 1; i <= m; i++ { 55 | for j := 1; j <= n; j++ { 56 | if exp[i-1] == '*' { 57 | // If we see a '*' in pattern: 58 | // 1) We ignore '*' character and consider 59 | // next character in the pattern. 60 | // 2) We ignore one character in the input str 61 | // and consider next character. 62 | lookup[i][j] = lookup[i-1][j] || lookup[i][j-1] 63 | } else if exp[i-1] == '?' || str[j-1] == exp[i-1] { 64 | // Condition when both the pattern and input string 65 | // have the same character. Also, '?' matches with all the 66 | // characters. 67 | lookup[i][j] = lookup[i-1][j-1] 68 | } else { 69 | // If characters don't match 70 | lookup[i][j] = false 71 | } 72 | } 73 | } 74 | return lookup[m][n] 75 | } 76 | 77 | /* 78 | true 79 | true 80 | */ 81 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/ActivitySelection.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Activity struct { 9 | start, stop int 10 | } 11 | 12 | func NewActivity(a, b int) *Activity { 13 | p := new(Activity) 14 | p.start = a 15 | p.stop = b 16 | return p 17 | } 18 | 19 | func MaxActivities(s, f []int, n int) { 20 | act := make([]*Activity, n) 21 | for i := 0; i < n; i++ { 22 | act[i] = NewActivity(s[i], f[i]) 23 | } 24 | 25 | // Sort the activities according to finish time. 26 | sort.Slice(act, func(i, j int) bool { 27 | return act[i].stop < act[j].stop 28 | }) 29 | 30 | i := 0 // The first activity at index 0 is always selected. 31 | fmt.Print("Activities are: (", act[i].start, ",", act[i].stop, ")") 32 | for j := 1; j < n; j++ { 33 | // Find the next activity whose start time is greater than or equal 34 | // to the finish time of the previous activity. 35 | if act[j].start >= act[i].stop { 36 | fmt.Print(", (", act[j].start, ",", act[j].stop, ")") 37 | i = j 38 | } 39 | } 40 | } 41 | 42 | func main() { 43 | s := []int{1, 5, 0, 3, 5, 6, 8} 44 | f := []int{2, 6, 5, 4, 9, 7, 9} 45 | n := len(s) 46 | MaxActivities(s, f, n) 47 | } 48 | 49 | /* 50 | Activities are: (1,2), (3,4), (5,6), (6,7), (8,9) 51 | */ 52 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/ChotaBhim.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "sort" 7 | ) 8 | 9 | func ChotaBhim(cups []int) int { 10 | size := len(cups) 11 | time := 60 12 | 13 | sort.Slice(cups, func(i, j int) bool { 14 | return cups[i] > cups[j] 15 | }) // Sort decreasing 16 | 17 | total := 0 18 | var index int 19 | var temp int 20 | for time > 0 { 21 | total += cups[0] 22 | cups[0] = int(math.Ceil(float64(cups[0]) / 2.0)) 23 | index = 0 24 | temp = cups[0] 25 | for index < size-1 && temp < cups[index+1] { 26 | cups[index] = cups[index+1] 27 | index += 1 28 | } 29 | cups[index] = temp 30 | time -= 1 31 | } 32 | fmt.Println("Total:", total) 33 | return total 34 | } 35 | 36 | func ChotaBhim2(cups []int) int { 37 | size := len(cups) 38 | time := 60 39 | cmp := func(a, b interface{}) bool { 40 | return a.(int) < b.(int) 41 | } 42 | hp := CreateHeap(cmp) 43 | 44 | for i := 0; i < size; i++ { 45 | hp.Add(cups[i]) 46 | } 47 | 48 | total := 0 49 | var value int 50 | for time > 0 { 51 | value = hp.Remove().(int) 52 | total += value 53 | value = int(math.Ceil(float64(value) / 2.0)) 54 | hp.Add(value) 55 | time -= 1 56 | } 57 | fmt.Println("Total:", total) 58 | return total 59 | } 60 | 61 | func main() { 62 | cups := []int{2, 1, 7, 4, 2} 63 | ChotaBhim(cups) 64 | cups2 := []int{2, 1, 7, 4, 2} 65 | ChotaBhim2(cups2) 66 | } 67 | 68 | /* 69 | Total: 76 70 | Total: 76 71 | */ 72 | 73 | type Heap struct { 74 | size int 75 | arr []interface{} 76 | comp func(x interface{}, y interface{}) bool 77 | } 78 | 79 | func CreateHeap(comp func(x interface{}, y interface{}) bool, args ...[]interface{}) *Heap { 80 | var arr []interface{} 81 | size := 0 82 | if len(args) > 0 { 83 | arrInput := args[0] 84 | arr = append(arr, arrInput...) 85 | size = len(arrInput) 86 | } 87 | 88 | h := &Heap{comp: comp, arr: arr, size: size} 89 | for i := size / 2; i >= 0; i-- { 90 | h.percolateDown(i) 91 | } 92 | 93 | return h 94 | } 95 | 96 | func (h *Heap) swap(i, j int) { 97 | h.arr[i], h.arr[j] = h.arr[j], h.arr[i] 98 | } 99 | 100 | func (h *Heap) percolateDown(parent int) { 101 | lChild := 2*parent + 1 102 | rChild := lChild + 1 103 | child := -1 104 | if lChild < h.size { 105 | child = lChild 106 | } 107 | if rChild < h.size && h.comp(h.arr[lChild], h.arr[rChild]) { 108 | child = rChild 109 | } 110 | if child != -1 && h.comp(h.arr[parent], h.arr[child]) { 111 | h.swap(parent, child) 112 | h.percolateDown(child) 113 | } 114 | } 115 | 116 | func (h *Heap) percolateUp(child int) { 117 | parent := (child - 1) / 2 118 | if parent >= 0 && h.comp(h.arr[parent], h.arr[child]) { 119 | h.swap(child, parent) 120 | h.percolateUp(parent) 121 | } 122 | } 123 | 124 | func (h *Heap) Add(value interface{}) { 125 | h.arr = append(h.arr, value) 126 | h.size++ 127 | h.percolateUp(h.size - 1) 128 | } 129 | 130 | func (h *Heap) Remove() interface{} { 131 | if h.IsEmpty() { 132 | fmt.Println("HeapEmptyException.") 133 | return 0 134 | } 135 | value := h.arr[0] 136 | h.arr[0] = h.arr[h.size-1] 137 | h.size-- 138 | h.percolateDown(0) 139 | h.arr = h.arr[0:h.size] 140 | return value 141 | } 142 | 143 | func (h *Heap) Delete(value interface{}) bool { 144 | for i := 0; i < h.size; i++ { 145 | if h.arr[i] == value { 146 | h.arr[i] = h.arr[h.size-1] 147 | h.size -= 1 148 | h.percolateUp(i) 149 | h.percolateDown(i) 150 | return true 151 | } 152 | } 153 | return false 154 | } 155 | 156 | func (h *Heap) IsEmpty() bool { 157 | return h.size == 0 158 | } 159 | 160 | func (h *Heap) Size() int { 161 | return h.size 162 | } 163 | 164 | func (h *Heap) Peek() interface{} { 165 | if h.IsEmpty() { 166 | fmt.Println("Heap empty exception.") 167 | return 0 168 | } 169 | return h.arr[0] 170 | } 171 | 172 | func (h *Heap) Print() { 173 | fmt.Println("Heap size:", h.size) 174 | fmt.Print("Heap Array:") 175 | for i := 0; i < h.size; i++ { 176 | fmt.Print(" ", h.arr[i]) 177 | } 178 | fmt.Println() 179 | } 180 | 181 | /* 182 | Total: 76 183 | Total: 76 184 | */ 185 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/FractionalKnapsack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Items struct { 9 | wt, cost int 10 | density float64 11 | } 12 | 13 | func NewItems(a, b int) *Items { 14 | p := new(Items) 15 | p.wt = a 16 | p.cost = b 17 | p.density = float64(b) / float64(a) 18 | return p 19 | } 20 | 21 | func GetMaxCostFractional(wt []int, cost []int, capacity int) float64 { 22 | totalCost := 0.0 23 | n := len(wt) 24 | itemList := make([]*Items, n) 25 | for i := 0; i < n; i++ { 26 | itemList[i] = NewItems(wt[i], cost[i]) 27 | } 28 | 29 | // Sort items by density in decreasing order. 30 | sort.Slice(itemList, func(i, j int) bool { 31 | return itemList[i].density > itemList[j].density 32 | }) 33 | 34 | for i := 0; i < n; i++ { 35 | if capacity-itemList[i].wt >= 0 { 36 | capacity -= itemList[i].wt 37 | totalCost += float64(itemList[i].cost) 38 | } else { 39 | totalCost += itemList[i].density * float64(capacity) 40 | break 41 | } 42 | } 43 | return totalCost 44 | } 45 | 46 | func main() { 47 | wt := []int{10, 40, 20, 30} 48 | cost := []int{60, 40, 90, 120} 49 | capacity := 50 50 | maxCost := GetMaxCostFractional(wt, cost, capacity) 51 | fmt.Println("Maximum cost obtained =", maxCost) 52 | } 53 | 54 | /* 55 | Maximum cost obtained = 230 56 | */ 57 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/HuffmanTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | c rune 9 | freq int 10 | left, right *Node 11 | } 12 | 13 | func NewNode(ch rune, fr int, l *Node, r *Node) *Node { 14 | p := new(Node) 15 | p.c = ch 16 | p.freq = fr 17 | p.left = l 18 | p.right = r 19 | return p 20 | } 21 | 22 | type HuffmanTree struct { 23 | root *Node 24 | } 25 | 26 | func NewHuffmanTree(arr []rune, freq []int) *HuffmanTree { 27 | huffTree := &HuffmanTree{} 28 | 29 | cmp := func(a, b interface{}) bool { 30 | return a.(*Node).freq > b.(*Node).freq 31 | } 32 | hp := CreateHeap(cmp) 33 | 34 | for i := 0; i < len(arr); i++ { 35 | node := NewNode(arr[i], freq[i], nil, nil) 36 | hp.Add(node) 37 | } 38 | 39 | for hp.Size() > 1 { 40 | lt := hp.Remove().(*Node) 41 | rt := hp.Remove().(*Node) 42 | nd := NewNode('+', lt.freq+rt.freq, lt, rt) 43 | hp.Add(nd) 44 | } 45 | huffTree.root = hp.Remove().(*Node) 46 | return huffTree 47 | } 48 | 49 | func (huffTree *HuffmanTree) printUtil(root *Node, s string) { 50 | if root.left == nil && root.right == nil { 51 | fmt.Println(string(root.c), " = "+s) 52 | return 53 | } 54 | huffTree.printUtil(root.left, s+"0") 55 | huffTree.printUtil(root.right, s+"1") 56 | } 57 | 58 | func (huffTree *HuffmanTree) Print() { 59 | fmt.Println("Char = Huffman code") 60 | huffTree.printUtil(huffTree.root, "") 61 | } 62 | 63 | func main() { 64 | ar := []rune{'A', 'B', 'C', 'D', 'E'} 65 | fr := []int{30, 25, 21, 14, 10} 66 | hf := NewHuffmanTree(ar, fr) 67 | hf.Print() 68 | } 69 | 70 | /* 71 | Char = Huffman code 72 | C = 00 73 | E = 010 74 | D = 011 75 | B = 10 76 | A = 11 77 | */ 78 | 79 | type Heap struct { 80 | size int 81 | arr []interface{} 82 | comp func(x interface{}, y interface{}) bool 83 | } 84 | 85 | func CreateHeap(comp func(x interface{}, y interface{}) bool, args ...[]interface{}) *Heap { 86 | var arr []interface{} 87 | size := 0 88 | if len(args) > 0 { 89 | arrInput := args[0] 90 | arr = append(arr, arrInput...) 91 | size = len(arrInput) 92 | } 93 | 94 | h := &Heap{comp: comp, arr: arr, size: size} 95 | for i := size / 2; i >= 0; i-- { 96 | h.percolateDown(i) 97 | } 98 | 99 | return h 100 | } 101 | 102 | func (h *Heap) swap(i, j int) { 103 | h.arr[i], h.arr[j] = h.arr[j], h.arr[i] 104 | } 105 | 106 | func (h *Heap) percolateDown(parent int) { 107 | lChild := 2*parent + 1 108 | rChild := lChild + 1 109 | child := -1 110 | if lChild < h.size { 111 | child = lChild 112 | } 113 | if rChild < h.size && h.comp(h.arr[lChild], h.arr[rChild]) { 114 | child = rChild 115 | } 116 | if child != -1 && h.comp(h.arr[parent], h.arr[child]) { 117 | h.swap(parent, child) 118 | h.percolateDown(child) 119 | } 120 | } 121 | 122 | func (h *Heap) percolateUp(child int) { 123 | parent := (child - 1) / 2 124 | if parent >= 0 && h.comp(h.arr[parent], h.arr[child]) { 125 | h.swap(child, parent) 126 | h.percolateUp(parent) 127 | } 128 | } 129 | 130 | func (h *Heap) Add(value interface{}) { 131 | h.arr = append(h.arr, value) 132 | h.size++ 133 | h.percolateUp(h.size - 1) 134 | } 135 | 136 | func (h *Heap) Remove() interface{} { 137 | if h.IsEmpty() { 138 | fmt.Println("HeapEmptyException.") 139 | return 0 140 | } 141 | value := h.arr[0] 142 | h.arr[0] = h.arr[h.size-1] 143 | h.size-- 144 | h.percolateDown(0) 145 | h.arr = h.arr[0:h.size] 146 | return value 147 | } 148 | 149 | func (h *Heap) Delete(value interface{}) bool { 150 | for i := 0; i < h.size; i++ { 151 | if h.arr[i] == value { 152 | h.arr[i] = h.arr[h.size-1] 153 | h.size -= 1 154 | h.percolateUp(i) 155 | h.percolateDown(i) 156 | return true 157 | } 158 | } 159 | return false 160 | } 161 | 162 | func (h *Heap) IsEmpty() bool { 163 | return h.size == 0 164 | } 165 | 166 | func (h *Heap) Size() int { 167 | return h.size 168 | } 169 | 170 | func (h *Heap) Peek() interface{} { 171 | if h.IsEmpty() { 172 | fmt.Println("Heap empty exception.") 173 | return 0 174 | } 175 | return h.arr[0] 176 | } 177 | 178 | func (h *Heap) Print() { 179 | fmt.Println("Heap size:", h.size) 180 | fmt.Print("Heap Array:") 181 | for i := 0; i < h.size; i++ { 182 | fmt.Print(" ", h.arr[i]) 183 | } 184 | fmt.Println() 185 | } 186 | 187 | func minComp(i, j interface{}) bool { 188 | return i.(int) > j.(int) 189 | } 190 | 191 | func maxComp(i, j interface{}) bool { 192 | return i.(int) < j.(int) 193 | } 194 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/JobSequencing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Job struct { 9 | id rune 10 | deadline int 11 | profit int 12 | } 13 | 14 | func NewJob(id rune, deadline int, profit int) *Job { 15 | p := new(Job) 16 | p.id = id 17 | p.deadline = deadline 18 | p.profit = profit 19 | return p 20 | } 21 | 22 | type JobSequencing struct { 23 | jobs []*Job 24 | n int 25 | maxDL int 26 | } 27 | 28 | func NewJobSequencing(ids []rune, deadlines []int, profits []int, n int) *JobSequencing { 29 | jobSeq := &JobSequencing{} 30 | jobSeq.jobs = make([]*Job, n) 31 | jobSeq.n = n 32 | 33 | jobSeq.maxDL = deadlines[0] 34 | for i := 1; i < n; i++ { 35 | if deadlines[i] > jobSeq.maxDL { 36 | jobSeq.maxDL = deadlines[i] 37 | } 38 | } 39 | 40 | for i := 0; i < n; i++ { 41 | jobSeq.jobs[i] = NewJob(ids[i], deadlines[i], profits[i]) 42 | } 43 | return jobSeq 44 | } 45 | 46 | func (jobSeq *JobSequencing) Print() { 47 | // Sort jobs based on profit in descending order 48 | sort.Slice(jobSeq.jobs, func(i, j int) bool { 49 | return jobSeq.jobs[i].profit > jobSeq.jobs[j].profit 50 | }) 51 | 52 | // Initialize result array to track job scheduling 53 | result := make([]bool, jobSeq.maxDL) 54 | // Initialize job array to store selected jobs 55 | job := make([]rune, jobSeq.maxDL) 56 | profit := 0 57 | 58 | // Iterate over the jobs and assign them to the time slots 59 | for i := 0; i < jobSeq.n; i++ { 60 | // Find a time slot for the current job starting from its deadline 61 | for j := jobSeq.jobs[i].deadline - 1; j >= 0; j-- { 62 | // If the time slot is available, assign the job to it 63 | if !result[j] { 64 | result[j] = true 65 | job[j] = jobSeq.jobs[i].id 66 | profit += jobSeq.jobs[i].profit 67 | break 68 | } 69 | } 70 | } 71 | 72 | fmt.Println("Profit is:", profit) 73 | fmt.Print("Jobs selected are: ") 74 | for i := 0; i < jobSeq.maxDL; i++ { 75 | if job[i] != '0' { 76 | fmt.Print(string(job[i]), " ") 77 | } 78 | } 79 | } 80 | 81 | func main() { 82 | id := []rune{'a', 'b', 'c', 'd', 'e'} 83 | deadline := []int{3, 1, 2, 4, 4} 84 | profit := []int{50, 40, 27, 31, 30} 85 | js := NewJobSequencing(id, deadline, profit, 5) 86 | js.Print() 87 | } 88 | 89 | /* 90 | Profit is: 151 91 | Jobs selected are: b e a d 92 | */ 93 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/JoinRopes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | // JoinRopes joins the ropes and returns the total cost 9 | func JoinRopes(ropes []int, size int) int { 10 | // Sort ropes in decreasing order 11 | sort.Slice(ropes, func(i, j int) bool { 12 | return ropes[i] > ropes[j] 13 | }) 14 | 15 | total := 0 16 | value := 0 17 | var index int 18 | length := size 19 | 20 | // Join ropes until there are at least 2 ropes remaining 21 | for length >= 2 { 22 | value = ropes[length-1] + ropes[length-2] // Combine the last two ropes 23 | total += value // Add the combined value to the total cost 24 | index = length - 2 25 | 26 | // Shift ropes to make room for the combined rope 27 | for index > 0 && ropes[index-1] < value { 28 | ropes[index] = ropes[index-1] 29 | index -= 1 30 | } 31 | 32 | ropes[index] = value // Place the combined rope in the appropriate position 33 | length-- 34 | } 35 | 36 | fmt.Println("Total:", total) 37 | return total 38 | } 39 | 40 | // JoinRopes2 joins the ropes using a heap and returns the total cost 41 | func JoinRopes2(ropes []int, size int) int { 42 | // Define the comparison function for the heap 43 | cmp := func(a, b interface{}) bool { 44 | return a.(int) > b.(int) 45 | } 46 | 47 | // Create a heap and add the ropes to it 48 | hp := CreateHeap(cmp) 49 | for i := 0; i < size; i++ { 50 | hp.Add(ropes[i]) 51 | } 52 | 53 | total := 0 54 | value := 0 55 | 56 | // Combine ropes until there is only one rope remaining in the heap 57 | for hp.Size() > 1 { 58 | value = hp.Remove().(int) // Remove the smallest two ropes from the heap 59 | value += hp.Remove().(int) 60 | hp.Add(value) // Add the combined rope back to the heap 61 | total += value 62 | } 63 | 64 | fmt.Println("Total:", total) 65 | return total 66 | } 67 | 68 | func main() { 69 | ropes := []int{4, 3, 2, 6} 70 | JoinRopes(ropes, len(ropes)) 71 | 72 | rope2 := []int{4, 3, 2, 6} 73 | JoinRopes2(rope2, len(rope2)) 74 | } 75 | 76 | /* 77 | Total: 29 78 | Total: 29 79 | */ 80 | 81 | // Heap struct represents a binary heap 82 | type Heap struct { 83 | size int 84 | arr []interface{} 85 | comp func(x interface{}, y interface{}) bool 86 | } 87 | 88 | // CreateHeap creates a new heap with the given comparison function 89 | func CreateHeap(comp func(x interface{}, y interface{}) bool, args ...[]interface{}) *Heap { 90 | var arr []interface{} 91 | size := 0 92 | if len(args) > 0 { 93 | arrInput := args[0] 94 | arr = append(arr, arrInput...) 95 | size = len(arrInput) 96 | } 97 | 98 | h := &Heap{comp: comp, arr: arr, size: size} 99 | 100 | // Build the heap from the input array 101 | for i := (size / 2); i >= 0; i-- { 102 | h.percolateDown(i) 103 | } 104 | 105 | return h 106 | } 107 | 108 | // swap swaps the elements at the given indices in the heap's array 109 | func (h *Heap) swap(i, j int) { 110 | h.arr[i], h.arr[j] = h.arr[j], h.arr[i] 111 | } 112 | 113 | // percolateDown moves the element at the given index down the heap to its correct position 114 | func (h *Heap) percolateDown(parent int) { 115 | lChild := 2*parent + 1 116 | rChild := lChild + 1 117 | child := -1 118 | 119 | if lChild < h.size { 120 | child = lChild 121 | } 122 | 123 | if rChild < h.size && h.comp(h.arr[lChild], h.arr[rChild]) { 124 | child = rChild 125 | } 126 | 127 | if child != -1 && h.comp(h.arr[parent], h.arr[child]) { 128 | h.swap(parent, child) 129 | h.percolateDown(child) 130 | } 131 | } 132 | 133 | // percolateUp moves the element at the given index up the heap to its correct position 134 | func (h *Heap) percolateUp(child int) { 135 | parent := (child - 1) / 2 136 | 137 | if parent >= 0 && h.comp(h.arr[parent], h.arr[child]) { 138 | h.swap(child, parent) 139 | h.percolateUp(parent) 140 | } 141 | } 142 | 143 | // Add adds a new element to the heap 144 | func (h *Heap) Add(value interface{}) { 145 | h.arr = append(h.arr, value) 146 | h.size++ 147 | h.percolateUp(h.size - 1) 148 | } 149 | 150 | // Remove removes and returns the smallest element from the heap 151 | func (h *Heap) Remove() interface{} { 152 | if h.IsEmpty() { 153 | fmt.Println("HeapEmptyException.") 154 | return 0 155 | } 156 | 157 | value := h.arr[0] 158 | h.arr[0] = h.arr[h.size-1] 159 | h.size-- 160 | h.percolateDown(0) 161 | h.arr = h.arr[0:h.size] 162 | return value 163 | } 164 | 165 | // Delete deletes the given value from the heap 166 | func (h *Heap) Delete(value interface{}) bool { 167 | for i := 0; i < h.size; i++ { 168 | if h.arr[i] == value { 169 | h.arr[i] = h.arr[h.size-1] 170 | h.size -= 1 171 | h.percolateUp(i) 172 | h.percolateDown(i) 173 | return true 174 | } 175 | } 176 | return false 177 | } 178 | 179 | // IsEmpty checks if the heap is empty 180 | func (h *Heap) IsEmpty() bool { 181 | return (h.size == 0) 182 | } 183 | 184 | // Size returns the size of the heap 185 | func (h *Heap) Size() int { 186 | return h.size 187 | } 188 | 189 | // Peek returns the smallest element in the heap without removing it 190 | func (h *Heap) Peek() interface{} { 191 | if h.IsEmpty() { 192 | fmt.Println("Heap empty exception.") 193 | return 0 194 | } 195 | return h.arr[0] 196 | } 197 | 198 | // Print prints the heap's size and array 199 | func (h *Heap) Print() { 200 | fmt.Println("Heap size:", h.size) 201 | fmt.Print("Heap Array:") 202 | for i := 0; i < h.size; i++ { 203 | fmt.Print(" ", h.arr[i]) 204 | } 205 | fmt.Println() 206 | } 207 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/Knapsack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Item struct { 9 | weight int 10 | cost int 11 | density float64 12 | } 13 | 14 | func NewItem(weight, cost int) *Item { 15 | return &Item{ 16 | weight: weight, 17 | cost: cost, 18 | density: float64(cost) / float64(weight), 19 | } 20 | } 21 | 22 | func GetMaxCostGreedy(weights []int, costs []int, capacity int) int { 23 | totalCost := 0 24 | n := len(weights) 25 | items := make([]*Item, n) 26 | 27 | for i := 0; i < n; i++ { 28 | items[i] = NewItem(weights[i], costs[i]) 29 | } 30 | 31 | sort.Slice(items, func(i, j int) bool { 32 | return items[i].density > items[j].density 33 | }) 34 | 35 | for i := 0; i < n && capacity > 0; i++ { 36 | if capacity-items[i].weight >= 0 { 37 | capacity -= items[i].weight 38 | totalCost += items[i].cost 39 | } 40 | } 41 | 42 | return totalCost 43 | } 44 | 45 | func main() { 46 | weights := []int{10, 40, 20, 30} 47 | costs := []int{60, 40, 90, 120} 48 | capacity := 50 49 | maxCost := GetMaxCostGreedy(weights, costs, capacity) 50 | fmt.Println("Maximum cost obtained:", maxCost) 51 | } 52 | 53 | /* 54 | Maximum cost obtained: 150 55 | */ 56 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/MultipleStageGraph.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | var INF = math.MaxInt32 9 | 10 | // GraphShortestDist returns the shortest distance from 0 to N-1. 11 | func GraphShortestDist(graph [][]int, n int) int { 12 | // dist[i] is going to store shortest distance from node i to node n-1. 13 | dist := make([]int, n) 14 | for i := range dist { 15 | dist[i] = INF 16 | } 17 | path := make([]int, n) 18 | var value int 19 | dist[0] = 0 20 | path[0] = -1 21 | 22 | // Calculating shortest path for the nodes 23 | for i := 0; i < n; i++ { 24 | // Check all nodes of next 25 | for j := i; j < n; j++ { 26 | // Reject if no edge exists 27 | if graph[i][j] == INF { 28 | continue 29 | } 30 | value = graph[i][j] + dist[i] 31 | if dist[j] > value { 32 | dist[j] = value 33 | path[j] = i 34 | } 35 | } 36 | } 37 | 38 | value = n - 1 39 | fmt.Print("Path: ") 40 | for value != -1 { 41 | fmt.Print(value, " ") 42 | value = path[value] 43 | } 44 | fmt.Println() 45 | return dist[n-1] 46 | } 47 | 48 | func main() { 49 | graph := [][]int{ 50 | {INF, 1, 2, 5, INF, INF, INF, INF}, 51 | {INF, INF, INF, INF, 4, 11, INF, INF}, 52 | {INF, INF, INF, INF, 9, 5, 16, INF}, 53 | {INF, INF, INF, INF, INF, INF, 2, INF}, 54 | {INF, INF, INF, INF, INF, INF, INF, 18}, 55 | {INF, INF, INF, INF, INF, INF, INF, 13}, 56 | {INF, INF, INF, INF, INF, INF, INF, 2}, 57 | {INF, INF, INF, INF, INF, INF, INF, INF}, 58 | } 59 | 60 | fmt.Println("Total Cost:", GraphShortestDist(graph, 8)) 61 | } 62 | 63 | /* 64 | Path: 7 6 3 0 65 | Total Cost: 9 66 | */ 67 | -------------------------------------------------------------------------------- /AlgorithmsChapters/Greedy/OptimalMergePattern.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func OptimalMergePattern(lists []int, size int) int { 8 | cmp := func(a, b interface{}) bool { 9 | return a.(int) > b.(int) 10 | } 11 | hp := CreateHeap(cmp) 12 | 13 | for i := 0; i < size; i++ { 14 | hp.Add(lists[i]) 15 | } 16 | total := 0 17 | value := 0 18 | for hp.Size() > 1 { 19 | value = hp.Remove().(int) 20 | value += hp.Remove().(int) 21 | hp.Add(value) 22 | total += value 23 | } 24 | return total 25 | } 26 | 27 | func main() { 28 | lists := []int{4, 3, 2, 6} 29 | fmt.Println("Total:", OptimalMergePattern(lists, len(lists))) 30 | } 31 | 32 | /* 33 | Total: 29 34 | */ 35 | 36 | type Heap struct { 37 | size int 38 | arr []interface{} 39 | comp func(x interface{}, y interface{}) bool 40 | } 41 | 42 | func CreateHeap(comp func(x interface{}, y interface{}) bool, args ...[]interface{}) *Heap { 43 | var arr []interface{} 44 | size := 0 45 | if len(args) > 0 { 46 | arrInput := args[0] 47 | arr = append(arr, arrInput...) 48 | size = len(arrInput) 49 | } 50 | 51 | h := &Heap{comp: comp, arr: arr, size: size} 52 | for i := (size / 2); i >= 0; i-- { 53 | h.percolateDown(i) 54 | } 55 | 56 | return h 57 | } 58 | 59 | func (h *Heap) swap(i, j int) { 60 | h.arr[i], h.arr[j] = h.arr[j], h.arr[i] 61 | } 62 | 63 | func (h *Heap) percolateDown(parent int) { 64 | lChild := 2*parent + 1 65 | rChild := lChild + 1 66 | child := -1 67 | if lChild < h.size { 68 | child = lChild 69 | } 70 | if rChild < h.size && h.comp(h.arr[lChild], h.arr[rChild]) { 71 | child = rChild 72 | } 73 | if child != -1 && h.comp(h.arr[parent], h.arr[child]) { 74 | h.swap(parent, child) 75 | h.percolateDown(child) 76 | } 77 | } 78 | 79 | func (h *Heap) percolateUp(child int) { 80 | parent := (child - 1) / 2 81 | if parent >= 0 && h.comp(h.arr[parent], h.arr[child]) { 82 | h.swap(child, parent) 83 | h.percolateUp(parent) 84 | } 85 | } 86 | 87 | func (h *Heap) Add(value interface{}) { 88 | h.arr = append(h.arr, value) 89 | h.size++ 90 | h.percolateUp(h.size - 1) 91 | } 92 | 93 | func (h *Heap) Remove() interface{} { 94 | if h.IsEmpty() { 95 | fmt.Println("HeapEmptyException.") 96 | return 0 97 | } 98 | value := h.arr[0] 99 | h.arr[0] = h.arr[h.size-1] 100 | h.size-- 101 | h.percolateDown(0) 102 | h.arr = h.arr[0:h.size] 103 | return value 104 | } 105 | 106 | func (h *Heap) Delete(value interface{}) bool { 107 | for i := 0; i < h.size; i++ { 108 | if h.arr[i] == value { 109 | h.arr[i] = h.arr[h.size-1] 110 | h.size -= 1 111 | h.percolateUp(i) 112 | h.percolateDown(i) 113 | return true 114 | } 115 | } 116 | return false 117 | } 118 | 119 | func (h *Heap) IsEmpty() bool { 120 | return (h.size == 0) 121 | } 122 | 123 | func (h *Heap) Size() int { 124 | return h.size 125 | } 126 | 127 | func (h *Heap) Peek() interface{} { 128 | if h.IsEmpty() { 129 | fmt.Println("Heap empty exception.") 130 | return 0 131 | } 132 | return h.arr[0] 133 | } 134 | 135 | func (h *Heap) Print() { 136 | fmt.Println("Heap size:", h.size) 137 | fmt.Print("Heap Array:") 138 | for i := 0; i < h.size; i++ { 139 | fmt.Print(" ", h.arr[i]) 140 | } 141 | fmt.Println() 142 | } 143 | -------------------------------------------------------------------------------- /Basics/AccesserModifier.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type MyInt int 6 | 7 | func (data MyInt) increment1() { 8 | data = data + 1 9 | } 10 | 11 | func (data *MyInt) increment2() { 12 | *data = *data + 1 13 | } 14 | 15 | func main() { 16 | var data MyInt = 1 17 | fmt.Println("value before increment1() call :", data) 18 | data.increment1() 19 | fmt.Println("value after increment1() call :", data) 20 | data.increment2() 21 | fmt.Println("value after increment2() call :", data) 22 | } 23 | /* 24 | value before increment1() call : 1 25 | value after increment1() call : 1 26 | value after increment2() call : 2 27 | */ -------------------------------------------------------------------------------- /Basics/Array.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var arr [10]int 7 | fmt.Println(arr) 8 | for i := 0; i < 10; i++ { 9 | arr[i] = i 10 | } 11 | fmt.Println(arr) 12 | count := len(arr) 13 | fmt.Println("Length of array", count) 14 | } 15 | 16 | /* 17 | [0 0 0 0 0 0 0 0 0 0] 18 | [0 1 2 3 4 5 6 7 8 9] 19 | Length of array 10 20 | */ 21 | -------------------------------------------------------------------------------- /Basics/Bulb.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type BulbInterface interface { 8 | turnOn() 9 | turnOff() 10 | isOnFun() bool 11 | } 12 | 13 | const ( 14 | SMALL = iota 15 | MEDIUM 16 | LARGE 17 | ) 18 | 19 | type Bulb struct { 20 | isOn bool 21 | size int 22 | } 23 | 24 | func (b *Bulb) getBulfSize() int { 25 | return b.size 26 | } 27 | 28 | func (b *Bulb) setBulbSize(s int) { 29 | b.size = s 30 | } 31 | 32 | func (b *Bulb) turnOn() { 33 | b.isOn = true 34 | } 35 | 36 | func (b *Bulb) turnOff() { 37 | b.isOn = false 38 | } 39 | 40 | func (b *Bulb) isOnFun() bool { 41 | return b.isOn 42 | } 43 | 44 | type AdvanceBulb struct { 45 | Bulb 46 | intensity int 47 | } 48 | 49 | func (b *AdvanceBulb) setIntersity(i int) { 50 | b.intensity = i 51 | } 52 | 53 | func (b *AdvanceBulb) getIntersity() int { 54 | return b.intensity 55 | } 56 | 57 | func getBulbStatus(bi BulbInterface) { 58 | fmt.Println("bulb is on: ", bi.isOnFun()) 59 | } 60 | 61 | func main() { 62 | b := Bulb{false, SMALL} 63 | fmt.Println("bulb is on return : ", b.isOnFun()) 64 | b.turnOn() 65 | fmt.Println("bulb is on return : ", b.isOnFun()) 66 | ab := AdvanceBulb{Bulb{false, MEDIUM}, 10} 67 | fmt.Println("bulb is on return : ", ab.isOnFun(), " and its intensity is : ", ab.getIntersity()) 68 | fmt.Println(ab.isOnFun()) 69 | 70 | getBulbStatus(&b) 71 | getBulbStatus(&ab) 72 | } -------------------------------------------------------------------------------- /Basics/For.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main1() { 6 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 7 | sum := 0 8 | for i := 0; i < len(numbers); i++ { 9 | sum += numbers[i] 10 | } 11 | fmt.Println("Sum is :: ", sum) 12 | } 13 | 14 | func main2() { 15 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 16 | sum := 0 17 | for _, val := range numbers { 18 | sum += val 19 | } 20 | fmt.Println("Sum is :: ", sum) 21 | } 22 | 23 | func main3() { 24 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 25 | sum := 0 26 | i := 0 27 | n := len(numbers) 28 | for i < n { 29 | sum += numbers[i] 30 | i++ 31 | } 32 | fmt.Println("Sum is :: ", sum) 33 | } 34 | 35 | func main4() { 36 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 37 | sum := 0 38 | i := 0 39 | for { 40 | sum += numbers[i] 41 | i++ 42 | if i >= len(numbers) { 43 | break 44 | } 45 | } 46 | fmt.Println("Sum is :: ", sum) 47 | } 48 | 49 | func main() { 50 | main1() 51 | main2() 52 | main3() 53 | main4() 54 | } -------------------------------------------------------------------------------- /Basics/Helloworld.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* This is a Multiple line 6 | comment */ 7 | 8 | // This is a Single line comment 9 | func main() { 10 | 11 | fmt.Println("Hello, World!") 12 | } 13 | -------------------------------------------------------------------------------- /Basics/Limit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | const PI2 = 3.1428 8 | 9 | func main() { 10 | maxInt8 := math.MaxInt8 11 | minInt8 := math.MinInt8 12 | 13 | maxInt16 := math.MaxInt16 14 | minInt16 := math.MinInt16 15 | 16 | maxInt32 := math.MaxInt32 17 | minInt32 := math.MinInt32 18 | 19 | maxInt64 := math.MaxInt64 20 | minInt64 := math.MinInt64 21 | 22 | maxUint8 := math.MaxUint8 23 | maxUint16 := math.MaxUint16 24 | maxUint32 := math.MaxUint32 25 | var maxUint64 uint64 = math.MaxUint64 26 | maxFloat32 := math.MaxFloat32 27 | maxFloat64 := math.MaxFloat64 28 | 29 | fmt.Println("Range of Int8 :: ", minInt8, " to ", maxInt8) 30 | fmt.Println("Range of Int16 :: ", minInt16, " to ", maxInt16) 31 | fmt.Println("Range of Int32 :: ", minInt32, " to ", maxInt32) 32 | fmt.Println("Range of Int64 :: ", minInt64, " to ", maxInt64) 33 | fmt.Println("Max Uint8 :: ", maxUint8) 34 | fmt.Println("Max Uint16 :: ", maxUint16) 35 | fmt.Println("Max Uint32 :: ", maxUint32) 36 | fmt.Println("Max Uint64 :: ", maxUint64) 37 | fmt.Println("Max Float32 :: ", maxFloat32) 38 | fmt.Println("Max Float64 :: ", maxFloat64) 39 | } 40 | /* 41 | 42 | Range of Int8 :: -128 to 127 43 | Range of Int16 :: -32768 to 32767 44 | Range of Int32 :: -2147483648 to 2147483647 45 | Range of Int64 :: -9223372036854775808 to 9223372036854775807 46 | Max Uint8 :: 255 47 | Max Uint16 :: 65535 48 | Max Uint32 :: 4294967295 49 | Max Uint64 :: 18446744073709551615 50 | Max Float32 :: 3.4028234663852886e+38 51 | Max Float64 :: 1.7976931348623157e+308 52 | 53 | */ -------------------------------------------------------------------------------- /Basics/LinkedList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type List struct { 8 | head *Node 9 | } 10 | 11 | type Node struct { 12 | value int 13 | next *Node 14 | } 15 | 16 | func (list *List) Insert(v int) *List { 17 | if list == nil { 18 | fmt.Println("list is not created.") 19 | return nil 20 | } 21 | temp := new(Node) 22 | temp.value = v 23 | temp.next = list.head 24 | list.head = temp 25 | return list 26 | } 27 | 28 | // Sum returns the sum of the list elements. 29 | func (list *List) Sum() int { 30 | if list == nil { 31 | fmt.Println("list is not created.") 32 | return 0 33 | } 34 | temp := list.head 35 | sum := 0 36 | for temp != nil { 37 | sum += temp.value 38 | temp = temp.next 39 | } 40 | return sum 41 | } 42 | 43 | func (list *List) Print() { 44 | if list == nil { 45 | fmt.Println("list is not created.") 46 | return 47 | } 48 | temp := list.head 49 | for temp != nil { 50 | fmt.Print(temp.value, " ") 51 | temp = temp.next 52 | } 53 | } 54 | 55 | func main() { 56 | // lst := new(List) 57 | lst := List{} 58 | lst.Insert(1) 59 | lst.Insert(2) 60 | lst.Insert(3) 61 | lst.Insert(1) 62 | lst.Insert(2) 63 | lst.Insert(3) 64 | fmt.Println(lst.Sum()) 65 | lst.Print() 66 | } -------------------------------------------------------------------------------- /Basics/Shape.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type Shape interface { 9 | Area() float64 10 | Perimeter() float64 11 | } 12 | 13 | type Rect struct { 14 | width float64 15 | height float64 16 | } 17 | 18 | type Circle struct { 19 | radius float64 20 | } 21 | 22 | func (r Rect) Area() float64 { 23 | return r.width * r.height 24 | } 25 | 26 | func (r Rect) Perimeter() float64 { 27 | return 2 * (r.width + r.height) 28 | } 29 | 30 | func (c Circle) Area() float64 { 31 | return math.Pi * c.radius * c.radius 32 | } 33 | 34 | func (c Circle) Perimeter() float64 { 35 | return 2 * math.Pi * c.radius 36 | } 37 | 38 | func TotalArea(shapes ...Shape) float64 { 39 | var area float64 40 | for _, s := range shapes { 41 | area += s.Area() 42 | } 43 | return area 44 | } 45 | 46 | func TotalPerimeter(shapes ...Shape) float64 { 47 | var peri float64 48 | for _, s := range shapes { 49 | peri += s.Perimeter() 50 | } 51 | return peri 52 | } 53 | 54 | func main() { 55 | r := Rect{width: 10, height: 10} 56 | fmt.Println("Area: ", r.Area()) 57 | fmt.Println("Perimeter: ", r.Perimeter()) 58 | 59 | ptr := &Rect{width: 10, height: 5} 60 | fmt.Println("Area: ", ptr.Area()) 61 | fmt.Println("Perimeter: ", ptr.Perimeter()) 62 | 63 | c := Circle{radius: 10} 64 | fmt.Println("Total Area: ", TotalArea(r, c)) 65 | fmt.Println("Total Perimeter: ", TotalPerimeter(r, c)) 66 | } 67 | 68 | /* 69 | Area: 100 70 | Perimeter: 40 71 | Area: 50 72 | Perimeter: 30 73 | Area: 414.1592653589793 74 | Perimeter: 102.83185307179586 75 | */ -------------------------------------------------------------------------------- /Basics/Tree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type TreeNode struct { 8 | value int 9 | left, right *TreeNode 10 | } 11 | 12 | type Tree struct { 13 | root *TreeNode 14 | } 15 | 16 | func (t *Tree) Add(value int) { 17 | t.root = Add(t.root, value) 18 | } 19 | 20 | func Add(n *TreeNode, value int) *TreeNode { 21 | if n == nil { 22 | // Equivalent to return &Tree{value: value}. 23 | n = new(TreeNode) 24 | n.value = value 25 | return n 26 | } 27 | if value < n.value { 28 | n.left = Add(n.left, value) 29 | } else { 30 | n.right = Add(n.right, value) 31 | } 32 | return n 33 | } 34 | 35 | func (t *Tree) InOrder() { 36 | InOrder(t.root) 37 | fmt.Println() 38 | } 39 | 40 | func InOrder(n *TreeNode) { 41 | if n == nil { 42 | return 43 | } 44 | InOrder(n.left) 45 | fmt.Print(n.value, " ") 46 | InOrder(n.right) 47 | } 48 | 49 | func main() { 50 | t := new(Tree) 51 | t.Add(2) 52 | t.Add(1) 53 | t.Add(3) 54 | t.Add(4) 55 | t.InOrder() 56 | } -------------------------------------------------------------------------------- /Basics/if.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func max(x, y int) int { 6 | if x > y { 7 | return x 8 | } else { 9 | return y 10 | } 11 | } 12 | 13 | func more(x, y int) bool { 14 | if x > y { 15 | return true 16 | } 17 | return false 18 | } 19 | 20 | // If with precondition. 21 | func maxAreaCheck(length int, width int, limit int) bool { 22 | if area := length * width; area < limit { 23 | return true 24 | } else { 25 | return false 26 | } 27 | } 28 | 29 | func main() { 30 | fmt.Println("Max : ", max(35, 33)) 31 | fmt.Println("More : ", more(35, 33)) 32 | fmt.Println("Max area check : ", maxAreaCheck(30, 10, 200)) 33 | } -------------------------------------------------------------------------------- /Basics/pointer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | data := 10 7 | ptr := &data 8 | 9 | fmt.Println("Value stored at variable var is ", data) 10 | fmt.Println("Value stored at variable var is ", *ptr) 11 | 12 | fmt.Println("The address of variable var is ", &data) 13 | fmt.Println("The address of variable var is ", ptr) 14 | } 15 | /* 16 | Value stored at variable var is 10 17 | Value stored at variable var is 10 18 | The address of variable var is 0xc04200e210 19 | The address of variable var is 0xc04200e210 20 | */ -------------------------------------------------------------------------------- /Basics/range.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 7 | sum := 0 8 | 9 | for index, val := range numbers { 10 | sum += val 11 | fmt.Print("[", index, ",", val, "] ") 12 | } 13 | 14 | fmt.Println("\nSum is :: ", sum) 15 | 16 | kvs := map[int]string{1: "apple", 2: "banana"} 17 | 18 | for k, v := range kvs { 19 | fmt.Println(k, " -> ", v) 20 | } 21 | 22 | for i, c := range "Hello, World!" { 23 | fmt.Print("[", i, ",", string(c), "] ") 24 | } 25 | } 26 | 27 | /* 28 | [0,1] [1,2] [2,3] [3,4] [4,5] [5,6] [6,7] [7,8] [8,9] [9,10] 29 | Sum is :: 55 30 | 1 -> apple 31 | 2 -> banana 32 | [0,H] [1,e] [2,l] [3,l] [4,o] [5,,] [6, ] [7,W] [8,o] [9,r] [10,l] [11,d] [12,!] 33 | */ -------------------------------------------------------------------------------- /Basics/string.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s := "hello, World!" 7 | r := []rune(s) 8 | r[0] = 'H' 9 | s2 := string(r) 10 | fmt.Println(s2) 11 | } 12 | -------------------------------------------------------------------------------- /Basics/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main1() { 8 | i := 2 9 | switch i { 10 | case 1: 11 | fmt.Println("one") 12 | case 2: 13 | fmt.Println("two") 14 | case 3: 15 | fmt.Println("three") 16 | default: 17 | fmt.Println("something else") 18 | } 19 | } 20 | 21 | func main2() { 22 | i := 2 23 | switch i { 24 | case 1, 2, 3: 25 | fmt.Println("one,two or three") 26 | default: 27 | fmt.Println("something else") 28 | } 29 | } 30 | 31 | func isEven(value int) bool { 32 | switch { 33 | case value%2 == 0: 34 | fmt.Println("I is even") 35 | return true 36 | default: 37 | fmt.Println("I is odd") 38 | return false 39 | } 40 | } 41 | 42 | // switch with precondition. 43 | func limitCheck(first, second int) bool { 44 | switch value := 100; { 45 | case value > first && value < second: 46 | return true 47 | case value > second || value < first: 48 | return false 49 | } 50 | return true 51 | } 52 | 53 | func main(){ 54 | main1() 55 | main2() 56 | fmt.Println(isEven(100)) 57 | fmt.Println(isEven(103)) 58 | fmt.Println(limitCheck(10,40)) 59 | fmt.Println(limitCheck(10,400)) 60 | } -------------------------------------------------------------------------------- /Basics/text.txt: -------------------------------------------------------------------------------- 1 | Every Go program start with a package declaration. 2 | Package main is required for a standalone executable. -------------------------------------------------------------------------------- /Basics/untitled.go: -------------------------------------------------------------------------------- 1 | 2 | func IncrementPassByValue(x int) { 3 | x++ 4 | } 5 | 6 | func IncrementPassByPointer(ptr *int) { 7 | (*ptr)++ 8 | } 9 | 10 | func main1() { 11 | i := 10 12 | fmt.Println("Value of i before increment is : ", i) 13 | IncrementPassByValue(i) 14 | fmt.Println("Value of i after increment is : ", i) 15 | 16 | fmt.Println("Value of i before increment is : ", i) 17 | IncrementPassByPointer(&i) 18 | fmt.Println("Value of i after increment is : ", i) 19 | } 20 | 21 | type coord struct { 22 | x int 23 | y int 24 | } 25 | 26 | 27 | 28 | func ArrayExample() { 29 | var arr [10]int 30 | for i := 0; i < 10; i++ { 31 | arr[i] = i 32 | } 33 | PrintSlice(arr[:]) 34 | } 35 | 36 | func SliceExample() { 37 | var s []int 38 | for i := 0; i < 10; i++ { 39 | s = append(s, i) 40 | } 41 | PrintSlice(s) 42 | } 43 | 44 | func PrintSlice(data []int) { 45 | count := len(data) 46 | fmt.Print("Values stored are : ") 47 | for i := 0; i < count; i++ { 48 | fmt.Print(" ", data[i]) 49 | } 50 | fmt.Println() 51 | } 52 | 53 | 54 | func VariableExample() { 55 | var1 := 100 56 | var2 := 200 57 | var3 := var1 + var2 58 | fmt.Println("Adding ", var1, " and ", var2, " will give ", var3) 59 | } 60 | 61 | func VectorExample() { 62 | var data [10]int 63 | for i := 0; i < 10; i++ { 64 | data[i] = i 65 | } 66 | PrintSlice(data[:]) 67 | } 68 | 69 | func twoDArrayExample() { 70 | var data [4][2]int 71 | count := 0 72 | for i := 0; i < 4; i++ { 73 | for j := 0; j < 2; j++ { 74 | count++ 75 | data[i][j] = count 76 | } 77 | } 78 | print2DArray(data, 4, 2) 79 | } 80 | 81 | func print2DArray(data [4][2]int, R int, C int) { 82 | for i := 0; i < R; i++ { 83 | for j := 0; j < C; j++ { 84 | fmt.Println(" ", data[i][j]) 85 | } 86 | } 87 | } 88 | 89 | 90 | 91 | func main6() { 92 | point := &coord{10, 10} 93 | fmt.Println("X axis coord value is ", point.x) 94 | fmt.Println("Y axis coord value is ", point.y) 95 | } 96 | 97 | func (s student) GetName() string { 98 | return s.name 99 | } 100 | 101 | func (s student) GetRollNo() int { 102 | return s.rollNo 103 | } 104 | 105 | type student struct { 106 | rollNo int 107 | name string 108 | } 109 | 110 | func main7() { 111 | stud := student{1, "johny"} 112 | fmt.Println(stud) 113 | fmt.Println("Student name ::", stud.name) // Accessing inner fields. 114 | 115 | pstud := &stud 116 | fmt.Println("Student name ::", pstud.name) // Accessing inner fields. 117 | 118 | fmt.Println(student{rollNo: 2, name: "Ann"}) // Named initialization. 119 | fmt.Println(student{name: "Ann", rollNo: 2}) // Order does not matter. 120 | fmt.Println(student{name: "Alice"}) // Default initialization of rollNo. 121 | } 122 | 123 | /* 124 | {1 johny} 125 | Student name :: johny 126 | Student name :: johny 127 | {2 Ann} 128 | {2 Ann} 129 | {0 Alice} 130 | */ 131 | 132 | 133 | func Sum(num1 int, num2 int) int { 134 | result := num1 + num2 135 | return result 136 | } 137 | 138 | func main8() { 139 | // calling a function to calculate sum 140 | result := Sum(10, 20) 141 | fmt.Println("Sum is : ", result) 142 | } 143 | 144 | func main9() { 145 | // local variable definition 146 | x := 10 147 | y := 20 148 | // calling a function to find sum 149 | result := Sum(x, y) 150 | fmt.Println("Sum is : ", result) 151 | } 152 | -------------------------------------------------------------------------------- /Basics/variable.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main1() { 6 | var v1 int 7 | var v2 int 8 | v1 = 100 9 | v2 = 200 10 | fmt.Println("Value stored in variable v1 :: ", v1) 11 | fmt.Println("Value stored in variable v2 :: ", v2) 12 | } 13 | 14 | func main2() { 15 | var v1, v2 int 16 | v1 = 100 17 | fmt.Println("Value stored in variable v1 :: ", v1) 18 | fmt.Println("Value stored in variable v2 :: ", v2) 19 | } 20 | 21 | func main3() { 22 | v1 := 100 23 | v2 := 200 24 | fmt.Println("Value stored in variable v1 :: ", v1) 25 | fmt.Println("Value stored in variable v2 :: ", v2) 26 | } 27 | 28 | const PI = 3.14 29 | 30 | // Declare global variables 31 | var g1 int = 100 32 | 33 | func main4() { 34 | // Declaring a variable in a function 35 | v1 := 10 36 | v2 := 20 37 | fmt.Println("Value stored in variable v1 :: ", v1) 38 | fmt.Println("Value stored in variable v2 :: ", v2) 39 | fmt.Println("Value stored in variable g1 :: ", g1) 40 | } 41 | 42 | func main(){ 43 | main1() 44 | main2() 45 | main3() 46 | main4() 47 | } -------------------------------------------------------------------------------- /Collections/Array.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main(){ 8 | var arr [10]int 9 | for i := 0; i < 10; i++ { 10 | arr[i] = i; 11 | } 12 | for i := 0; i < 10; i++ { 13 | fmt.Print(arr[i], " "); 14 | } 15 | } 16 | 17 | /* 18 | 0 1 2 3 4 5 6 7 8 9 19 | */ -------------------------------------------------------------------------------- /Collections/Counter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Counter map[interface{}]int 8 | 9 | func (s *Counter) Insert(key interface{}) { 10 | (*s)[key] += 1 11 | } 12 | func (s *Counter) Has(key interface{}) bool { 13 | _, ok := (*s)[key] 14 | return ok 15 | } 16 | func (s *Counter) Get(key interface{}) (int, bool) { 17 | val, ok := (*s)[key] 18 | return val, ok 19 | } 20 | 21 | func (s *Counter) Remove(key interface{}) { 22 | val, ok := (*s)[key] 23 | if ok == false { 24 | return 25 | } else if val == 1 { 26 | delete((*s), key) 27 | return 28 | } 29 | (*s)[key]-- 30 | } 31 | 32 | func main() { 33 | mp := make(Counter) 34 | mp.Insert("a") 35 | mp.Insert("b") 36 | mp.Insert("a") 37 | 38 | fmt.Println(mp.Has("a")) 39 | fmt.Println(mp.Has("b")) 40 | fmt.Println(mp.Has("c")) 41 | 42 | fmt.Println(mp.Get("a")) 43 | fmt.Println(mp.Get("b")) 44 | fmt.Println(mp.Get("c")) 45 | } 46 | 47 | /* 48 | true 49 | true 50 | false 51 | 2 true 52 | 1 true 53 | 0 false 54 | */ 55 | -------------------------------------------------------------------------------- /Collections/Heap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/heap" 5 | "fmt" 6 | ) 7 | 8 | type Heap struct { 9 | heap []interface{} 10 | comp func(x interface{}, y interface{}) bool 11 | } 12 | 13 | func NewHeap(comp func(x interface{}, y interface{}) bool) *Heap { 14 | hp := new(Heap) 15 | hp.comp = comp 16 | return hp 17 | } 18 | 19 | func NewMaxHeap() *Heap { 20 | cmp := func(a, b interface{}) bool { 21 | return a.(int) > b.(int) 22 | } 23 | hp := NewHeap(cmp) 24 | return hp 25 | } 26 | 27 | func NewMinHeap() *Heap { 28 | cmp := func(a, b interface{}) bool { 29 | return a.(int) < b.(int) 30 | } 31 | hp := NewHeap(cmp) 32 | return hp 33 | } 34 | 35 | func (hp Heap) Len() int { 36 | return len(hp.heap) 37 | } 38 | 39 | func (hp Heap) Less(i, j int) bool { 40 | return hp.comp(hp.heap[i], hp.heap[j]) 41 | } 42 | 43 | func (hp Heap) Swap(i, j int) { 44 | hp.heap[i], hp.heap[j] = hp.heap[j], hp.heap[i] 45 | } 46 | 47 | func (hp *Heap) Push(x interface{}) { 48 | hp.heap = append(hp.heap, x) 49 | } 50 | 51 | func (hp *Heap) Pop() interface{} { 52 | n := len(hp.heap) 53 | value := hp.heap[n-1] 54 | hp.heap = hp.heap[0 : n-1] 55 | return value 56 | } 57 | 58 | func (hp Heap) Print() { 59 | fmt.Println("Heap :", hp.heap) 60 | } 61 | 62 | func (hp Heap) Empty() bool { 63 | return len(hp.heap) == 0 64 | } 65 | 66 | func (hp Heap) Peek() interface{} { 67 | return hp.heap[0] 68 | } 69 | 70 | func main() { 71 | cmp := func(a, b interface{}) bool { 72 | return a.(int) < b.(int) 73 | } 74 | pq := NewHeap(cmp) 75 | 76 | arr := []int{1, 2, 10, 8, 7, 3, 4, 6, 5, 9} 77 | for _, i := range arr { 78 | heap.Push(pq, i) 79 | } 80 | 81 | pq.Print() 82 | fmt.Print("Dequeue from Heap :: ") 83 | for pq.Len() != 0 { 84 | fmt.Print(heap.Pop(pq), " ") 85 | } 86 | } 87 | 88 | /* 89 | Heap : [1 2 3 5 7 10 4 8 6 9] 90 | Dequeue from Heap :: 1 2 3 4 5 6 7 8 9 10 91 | */ -------------------------------------------------------------------------------- /Collections/Map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | m := make(map[string]int) 9 | m["Apple"] = 40 10 | m["Banana"] = 30 11 | m["Mango"] = 50 12 | 13 | for key, val := range m { 14 | fmt.Print("[ ", key, " @ ", val, " ]") 15 | } 16 | fmt.Println() 17 | 18 | v, ok := m["Apple"] 19 | if ok { 20 | fmt.Println("Apple available at price :", v) 21 | } else { 22 | fmt.Println("Apple unavailable.") 23 | } 24 | 25 | delete(m, "Apple") 26 | 27 | v, ok = m["Apple"] 28 | if ok { 29 | fmt.Println("Apple available at price :", v) 30 | } else { 31 | fmt.Println("Apple unavailable.") 32 | } 33 | } 34 | 35 | /* 36 | [ Apple @ 40 ][ Banana @ 30 ][ Mango @ 50 ] 37 | Apple available at price : 40 38 | Apple unavailable. 39 | */ -------------------------------------------------------------------------------- /Collections/Queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/golang-collections/collections/queue" 7 | ) 8 | 9 | func main() { 10 | que := queue.New() 11 | que.Enqueue(1) 12 | que.Enqueue(2) 13 | que.Enqueue(3) 14 | 15 | fmt.Println("Queue size :", que.Len()); 16 | fmt.Println("Queue peek :", que.Peek().(int)); 17 | fmt.Println("Queue remove :", que.Dequeue().(int)); 18 | fmt.Println("Queue isEmpty :", que.Len() == 0); 19 | } 20 | 21 | /* 22 | Queue size : 3 23 | Queue peek : 1 24 | Queue remove : 1 25 | Queue isEmpty : false 26 | */ -------------------------------------------------------------------------------- /Collections/Set.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/golang-collections/collections/set" 7 | ) 8 | 9 | func main() { 10 | st := set.New() 11 | st.Insert("Banana") 12 | st.Insert("Apple") 13 | st.Insert("Mango") 14 | 15 | fmt.Println("Apple present :", st.Has("Apple")) 16 | fmt.Println("Grapes present :", st.Has("Grapes")) 17 | st.Remove("Apple") 18 | fmt.Println("Apple present :", st.Has("Apple")) 19 | } 20 | 21 | /* 22 | Apple present : true 23 | Grapes present : false 24 | Apple present : false 25 | */ -------------------------------------------------------------------------------- /Collections/Set2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Set map[interface{}]bool 8 | 9 | func (s *Set) Insert(key interface{}) { 10 | (*s)[key] = true 11 | } 12 | 13 | func (s *Set) Remove(key interface{}) { 14 | delete((*s), key) 15 | } 16 | 17 | func (s *Set) Has(key interface{}) bool { 18 | return (*s)[key] 19 | } 20 | 21 | func main() { 22 | st := make(Set) 23 | st.Insert("Banana") 24 | st.Insert("Apple") 25 | st.Insert("Mango") 26 | 27 | fmt.Println("Apple present :", st.Has("Apple")) 28 | fmt.Println("Grapes present :", st.Has("Grapes")) 29 | st.Remove("Apple") 30 | fmt.Println("Apple present :", st.Has("Apple")) 31 | } 32 | 33 | /* 34 | Apple present : true 35 | Grapes present : false 36 | Apple present : false 37 | */ -------------------------------------------------------------------------------- /Collections/Stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/golang-collections/collections/stack" 7 | ) 8 | 9 | func main() { 10 | stk := stack.New() 11 | stk.Push(1) 12 | stk.Push(2) 13 | stk.Push(3) 14 | 15 | fmt.Println("Stack size :", stk.Len()); 16 | fmt.Println("Stack pop :", stk.Pop()); 17 | fmt.Println("Stack top :", stk.Peek()); 18 | fmt.Println("Stack isEmpty :", stk.Len() == 0); 19 | } 20 | 21 | /* 22 | Stack size : 3 23 | Stack pop : 3 24 | Stack top : 2 25 | Stack isEmpty : false 26 | */ -------------------------------------------------------------------------------- /Graph/hp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | 8 | type Heap struct { 9 | size int 10 | arr []interface{} 11 | comp func(x interface{}, y interface{}) bool 12 | } 13 | 14 | func CreateHeap(comp func(x interface{}, y interface{}) bool) *Heap { 15 | var arr []interface{} 16 | h := &Heap{comp: comp, arr : arr, size : 0} 17 | return h 18 | } 19 | 20 | func (h *Heap) swap(i, j int) { 21 | h.arr[i], h.arr[j] = h.arr[j], h.arr[i] 22 | } 23 | 24 | func (h *Heap) percolateDown(parent int) { 25 | lChild := 2 * parent + 1 26 | rChild := lChild + 1 27 | child := -1 28 | if lChild < h.size { 29 | child = lChild 30 | } 31 | if rChild < h.size && h.comp(h.arr[lChild], h.arr[rChild]) { 32 | child = rChild 33 | } 34 | if child != -1 && h.comp(h.arr[parent], h.arr[child]) { 35 | h.swap(parent, child) 36 | h.percolateDown(child) 37 | } 38 | } 39 | 40 | func (h *Heap) percolateUp(child int) { 41 | parent := (child - 1) / 2 42 | if parent >= 0 && h.comp(h.arr[parent], h.arr[child]) { 43 | h.swap(child, parent) 44 | h.percolateUp(parent) 45 | } 46 | } 47 | 48 | func (h *Heap) Add(value interface{}) { 49 | h.arr = append(h.arr, value) 50 | h.size++ 51 | h.percolateUp(h.size-1) 52 | } 53 | 54 | func (h *Heap) Remove() interface{} { 55 | if h.IsEmpty() { 56 | fmt.Println("HeapEmptyException.") 57 | return 0 58 | } 59 | value := h.arr[0] 60 | h.arr[0] = h.arr[h.size - 1] 61 | h.size-- 62 | h.percolateDown(0) 63 | h.arr = h.arr[0 : h.size] 64 | return value 65 | } 66 | 67 | 68 | func (h *Heap) Delete( value interface{}) bool { 69 | for i := 0; i < h.size; i++ { 70 | if (h.arr[i] == value) { 71 | h.arr[i] = h.arr[h.size - 1] 72 | h.size -= 1 73 | h.percolateUp(i) 74 | h.percolateDown(i) 75 | return true 76 | } 77 | } 78 | return false 79 | } 80 | 81 | func (h *Heap) IsEmpty() bool { 82 | return (h.size == 0) 83 | } 84 | 85 | func (h *Heap) Size() int { 86 | return h.size 87 | } 88 | 89 | func (h *Heap) Peek() interface{} { 90 | if h.IsEmpty() { 91 | fmt.Println("Heap empty exception.") 92 | return 0 93 | } 94 | return h.arr[0] 95 | } 96 | 97 | func (h *Heap) Print() { 98 | fmt.Println("Heap size :", h.size) 99 | fmt.Print("Heap Array :") 100 | for i := 0; i < h.size; i++ { 101 | fmt.Print(" ", h.arr[i]) 102 | } 103 | fmt.Println() 104 | } 105 | 106 | func minComp (i, j interface{}) bool { // always i < j in use 107 | return i.(int) > j.(int) // swaps for min heap 108 | } 109 | 110 | func maxComp (i, j interface{}) bool { // always i < j in use 111 | return i.(int) < j.(int) // swap for max heap. 112 | } 113 | 114 | //Testing Code 115 | func main1() { 116 | hp := CreateHeap(minComp) 117 | hp.Add(1) 118 | hp.Add(6) 119 | hp.Add(5) 120 | hp.Add(7) 121 | hp.Add(3) 122 | hp.Add(4) 123 | hp.Add(2) 124 | hp.Print() 125 | for !hp.IsEmpty() { 126 | fmt.Print(hp.Remove(), " ") 127 | } 128 | } 129 | 130 | /* 131 | Heap size : 7 132 | Heap Array : 1 3 2 7 6 5 4 133 | 1 2 3 4 5 6 7 134 | */ 135 | 136 | //Testing Code 137 | func main() { 138 | hp := CreateHeap(maxComp) 139 | hp.Add(1) 140 | hp.Add(6) 141 | hp.Add(5) 142 | hp.Add(7) 143 | hp.Add(3) 144 | hp.Add(4) 145 | hp.Add(2) 146 | hp.Print() 147 | for !hp.IsEmpty() { 148 | fmt.Print(hp.Remove(), " ") 149 | } 150 | } 151 | 152 | /* Testing Code 153 | func main2() { 154 | a := []int{1, 2, 10, 8, 7, 3, 4, 6, 5, 9} 155 | hp := CreateHeap(true, a)// Min Heap 156 | hp.Print() 157 | for !hp.IsEmpty() { 158 | fmt.Print(hp.Remove(), " ") 159 | } 160 | } 161 | /* 162 | Heap size : 10 163 | Heap Array : 1 2 3 5 7 10 4 6 8 9 164 | 1 2 3 4 5 6 7 8 9 10 165 | */ -------------------------------------------------------------------------------- /HashTable/HashTableLP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | EmptyNode byte = iota 7 | DeletedNode 8 | FilledNode 9 | ) 10 | 11 | type HashTable struct { 12 | Keys []int 13 | Values []int 14 | Flags []byte 15 | TableSize int 16 | } 17 | 18 | func NewHashTable(tableSize int) *HashTable { 19 | ht := &HashTable{ 20 | Keys: make([]int, tableSize+1), 21 | Values: make([]int, tableSize+1), 22 | Flags: make([]byte, tableSize+1), 23 | TableSize: tableSize, 24 | } 25 | return ht 26 | } 27 | 28 | func (ht *HashTable) ComputeHash(key int) int { 29 | return key % ht.TableSize 30 | } 31 | 32 | func (ht *HashTable) ResolverFun(index int) int { 33 | return index 34 | } 35 | 36 | func (ht *HashTable) Add(key int, args ...int) bool { 37 | value := key 38 | if len(args) > 0 { 39 | value = args[0] 40 | } 41 | 42 | hashValue := ht.ComputeHash(key) 43 | for i := 0; i < ht.TableSize; i++ { 44 | if ht.Flags[hashValue] == EmptyNode || ht.Flags[key] == DeletedNode { 45 | ht.Keys[key] = key 46 | ht.Values[hashValue] = value 47 | ht.Flags[hashValue] = FilledNode 48 | return true 49 | } else if ht.Flags[hashValue] == FilledNode && ht.Keys[hashValue] == key { 50 | ht.Values[hashValue] = value 51 | return true 52 | } 53 | 54 | hashValue += ht.ResolverFun(i) 55 | hashValue %= ht.TableSize 56 | } 57 | return false 58 | } 59 | 60 | func (ht *HashTable) Find(key int) bool { 61 | hashValue := ht.ComputeHash(key) 62 | for i := 0; i < ht.TableSize; i++ { 63 | if ht.Flags[hashValue] == EmptyNode { 64 | return false 65 | } 66 | if ht.Flags[hashValue] == FilledNode && ht.Keys[hashValue] == key { 67 | return true 68 | } 69 | hashValue += ht.ResolverFun(i) 70 | hashValue %= ht.TableSize 71 | } 72 | return false 73 | } 74 | 75 | func (ht *HashTable) Get(key int) int { 76 | hashValue := ht.ComputeHash(key) 77 | for i := 0; i < ht.TableSize; i++ { 78 | if ht.Flags[hashValue] == EmptyNode { 79 | return 0 80 | } 81 | if ht.Flags[hashValue] == FilledNode && ht.Keys[hashValue] == key { 82 | return ht.Values[hashValue] 83 | } 84 | hashValue += ht.ResolverFun(i) 85 | hashValue %= ht.TableSize 86 | } 87 | return 0 88 | } 89 | 90 | func (ht *HashTable) Remove(key int) bool { 91 | hashValue := ht.ComputeHash(key) 92 | for i := 0; i < ht.TableSize; i++ { 93 | if ht.Flags[hashValue] == EmptyNode { 94 | return false 95 | } 96 | if ht.Flags[hashValue] == FilledNode && ht.Keys[hashValue] == key { 97 | ht.Flags[hashValue] = DeletedNode 98 | return true 99 | } 100 | hashValue += ht.ResolverFun(i) 101 | hashValue %= ht.TableSize 102 | } 103 | return false 104 | } 105 | 106 | func (ht *HashTable) Print() { 107 | fmt.Print("Hash Table contains :: ") 108 | for i := 0; i < ht.TableSize; i++ { 109 | if ht.Flags[i] == FilledNode { 110 | fmt.Print("(", i, "=>", ht.Values[i], ") ") 111 | } 112 | } 113 | fmt.Println() 114 | } 115 | 116 | func main() { 117 | ht := NewHashTable(1000) 118 | ht.Add(1, 10) 119 | ht.Add(2, 20) 120 | ht.Add(3, 30) 121 | ht.Print() 122 | 123 | fmt.Println("Find key 2:", ht.Find(2)) 124 | fmt.Println("Value at key 2:", ht.Get(2)) 125 | ht.Remove(2) 126 | fmt.Println("Find key 2:", ht.Find(2)) 127 | } 128 | 129 | /* 130 | Hash Table contains :: (1=>10) (2=>20) (3=>30) 131 | Find key 2: true 132 | Value at key 2: 20 133 | Find key 2: false 134 | */ 135 | -------------------------------------------------------------------------------- /HashTable/HashTableSC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Node struct { 6 | key int 7 | value int 8 | next *Node 9 | } 10 | 11 | type HashTableSC struct { 12 | listArray [](*Node) 13 | tableSize int 14 | } 15 | 16 | func NewHashTableSC() *HashTableSC { 17 | h := &HashTableSC{ 18 | tableSize: 101, 19 | listArray: make([](*Node), 101), 20 | } 21 | return h 22 | } 23 | 24 | func (h *HashTableSC) ComputeHash(key int) int { 25 | return key % h.tableSize 26 | } 27 | 28 | func (h *HashTableSC) Add(key int, args ...int) { 29 | value := key 30 | if len(args) > 0 { 31 | value = args[0] 32 | } 33 | 34 | index := h.ComputeHash(key) 35 | temp := &Node{ 36 | key: key, 37 | value: value, 38 | next: h.listArray[index], 39 | } 40 | h.listArray[index] = temp 41 | } 42 | 43 | func (h *HashTableSC) Remove(key int) bool { 44 | index := h.ComputeHash(key) 45 | head := h.listArray[index] 46 | 47 | if head != nil && head.key == key { 48 | h.listArray[index] = head.next 49 | return true 50 | } 51 | 52 | var prev *Node 53 | for head != nil { 54 | if head.key == key { 55 | prev.next = head.next 56 | return true 57 | } 58 | prev = head 59 | head = head.next 60 | } 61 | 62 | return false 63 | } 64 | 65 | func (h *HashTableSC) Find(key int) bool { 66 | index := h.ComputeHash(key) 67 | head := h.listArray[index] 68 | 69 | for head != nil { 70 | if head.key == key { 71 | return true 72 | } 73 | head = head.next 74 | } 75 | 76 | return false 77 | } 78 | 79 | func (h *HashTableSC) Get(key int) int { 80 | index := h.ComputeHash(key) 81 | head := h.listArray[index] 82 | 83 | for head != nil { 84 | if head.key == key { 85 | return head.value 86 | } 87 | head = head.next 88 | } 89 | 90 | return 0 91 | } 92 | 93 | func (h *HashTableSC) Print() { 94 | fmt.Print("Hash Table contains :: ") 95 | for i := 0; i < h.tableSize; i++ { 96 | head := h.listArray[i] 97 | for head != nil { 98 | fmt.Print("(", i, "=>", head.value, ") ") 99 | head = head.next 100 | } 101 | } 102 | fmt.Println() 103 | } 104 | 105 | // Testing code. 106 | func main() { 107 | ht := NewHashTableSC() 108 | 109 | ht.Add(1, 10) 110 | ht.Add(2, 20) 111 | ht.Add(3, 30) 112 | ht.Print() 113 | 114 | fmt.Println("Find key 2:", ht.Find(2)) 115 | fmt.Println("Value at key 2:", ht.Get(2)) 116 | 117 | ht.Remove(2) 118 | fmt.Println("Find key 2:", ht.Find(2)) 119 | } 120 | 121 | /* 122 | Hash Table contains :: (1=>10) (2=>20) (3=>30) 123 | Find key 2: true 124 | Value at key 2: 20 125 | Find key 2: false 126 | */ 127 | -------------------------------------------------------------------------------- /IntroductoryChapters/Analysis.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func fun1(n int) int { 9 | m := 0 10 | for i := 0; i < n; i++ { 11 | m += 1 12 | } 13 | return m 14 | } 15 | 16 | func fun2(n int) int { 17 | m := 0 18 | for i := 0; i < n; i++ { 19 | for j := 0; j < n; j++ { 20 | m += 1 21 | } 22 | } 23 | return m 24 | } 25 | 26 | func fun3(n int) int { 27 | m := 0 28 | for i := 0; i < n; i++ { 29 | for j := 0; j < n; j++ { 30 | for k := 0; k < n; k++ { 31 | m += 1 32 | } 33 | } 34 | } 35 | return m 36 | } 37 | 38 | func fun4(n int) int { 39 | m := 0 40 | for i := 0; i < n; i++ { 41 | for j := i; j < n; j++ { 42 | for k := j + 1; k < n; k++ { 43 | m += 1 44 | } 45 | } 46 | } 47 | return m 48 | } 49 | 50 | func fun5(n int) int { 51 | m := 0 52 | for i := 0; i < n; i++ { 53 | for j := 0; j < i; j++ { 54 | m += 1 55 | } 56 | } 57 | return m 58 | } 59 | 60 | func fun6(n int) int { 61 | m := 0 62 | for i := 0; i < n; i++ { 63 | for j := i; j > 0; j-- { 64 | m += 1 65 | } 66 | } 67 | return m 68 | } 69 | 70 | func fun7(n int) int { 71 | m := 0 72 | for i := n; i > 0; i /= 2 { 73 | for j := 0; j < i; j++ { 74 | m += 1 75 | } 76 | } 77 | return m 78 | } 79 | 80 | func fun8(n int) int { 81 | m := 0 82 | for i := 1; i <= n; i *= 2 { 83 | for j := 0; j <= i; j++ { 84 | m += 1 85 | } 86 | } 87 | return m 88 | } 89 | 90 | func fun9(n int) int { 91 | m := 0 92 | i := 1 93 | for i < n { 94 | m += 1 95 | i = i * 2 96 | } 97 | return m 98 | } 99 | 100 | func fun10(n int) int { 101 | m := 0 102 | i := n 103 | for i > 0 { 104 | m += 1 105 | i = i / 2 106 | } 107 | return m 108 | } 109 | 110 | func fun11(n int) int { 111 | m := 0 112 | for i := 0; i < n; i++ { 113 | for j := 0; j < n; j++ { 114 | m += 1 115 | } 116 | } 117 | for i := 0; i < n; i++ { 118 | for k := 0; k < n; k++ { 119 | m += 1 120 | } 121 | } 122 | return m 123 | } 124 | 125 | func fun12(n int) int { 126 | m := 0 127 | for i := 0; i < n; i++ { 128 | sq := math.Sqrt(float64(n)) 129 | for j := 0; j < int(sq); j++ { 130 | m += 1 131 | } 132 | } 133 | return m 134 | } 135 | 136 | func fun13(n int) int { 137 | j := 0 138 | m := 0 139 | for i := 0; i < n; i++ { 140 | for ; j < n; j++ { 141 | m += 1 142 | } 143 | } 144 | return m 145 | } 146 | 147 | func main() { 148 | fmt.Println("N = 100, Number of instructions O(n) ::", fun1(100)) 149 | fmt.Println("N = 100, Number of instructions O(n^2) ::", fun2(100)) 150 | fmt.Println("N = 100, Number of instructions O(n^3) ::", fun3(100)) 151 | fmt.Println("N = 100, Number of instructions O(n^3) ::", fun4(100)) 152 | fmt.Println("N = 100, Number of instructions O(n^2) ::", fun5(100)) 153 | fmt.Println("N = 100, Number of instructions O(n^2) ::", fun6(100)) 154 | fmt.Println("N = 100, Number of instructions O(n) ::", fun7(100)) 155 | fmt.Println("N = 100, Number of instructions O(n) ::", fun8(100)) 156 | fmt.Println("N = 100, Number of instructions O(log(n)) ::", fun9(100)) 157 | fmt.Println("N = 100, Number of instructions O(log(n)) ::", fun10(100)) 158 | fmt.Println("N = 100, Number of instructions O(n^2) ::", fun11(100)) 159 | fmt.Println("N = 100, Number of instructions O(n^(3/2)) ::", fun12(100)) 160 | fmt.Println("N = 100, Number of instructions O(n) ::", fun13(100)) 161 | } 162 | 163 | /* 164 | N = 100, Number of instructions O(n) :: 100 165 | N = 100, Number of instructions O(n^2) :: 10000 166 | N = 100, Number of instructions O(n^3) :: 1000000 167 | N = 100, Number of instructions O(n^3) :: 166650 168 | N = 100, Number of instructions O(n^2) :: 4950 169 | N = 100, Number of instructions O(n^2) :: 4950 170 | N = 100, Number of instructions O(n) :: 197 171 | N = 100, Number of instructions O(n) :: 134 172 | N = 100, Number of instructions O(log(n)) :: 7 173 | N = 100, Number of instructions O(log(n)) :: 7 174 | N = 100, Number of instructions O(n^2) :: 20000 175 | N = 100, Number of instructions O(n^(3/2)) :: 1000 176 | N = 100, Number of instructions O(n) :: 100 177 | 178 | */ 179 | -------------------------------------------------------------------------------- /LinkedLIst/DoublyCircularLIst.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type DoublyCircularLinkedList struct { 6 | head *DCListNode 7 | tail *DCListNode 8 | count int 9 | } 10 | 11 | type DCListNode struct { 12 | value int 13 | next *DCListNode 14 | prev *DCListNode 15 | } 16 | 17 | func (list *DoublyCircularLinkedList) Size() int { 18 | return list.count 19 | } 20 | 21 | func (list *DoublyCircularLinkedList) IsEmpty() bool { 22 | return list.count == 0 23 | } 24 | 25 | func (list *DoublyCircularLinkedList) PeekHead() (int, bool) { 26 | if list.IsEmpty() { 27 | fmt.Println("EmptyListException") 28 | return 0, false 29 | } 30 | return list.head.value, true 31 | } 32 | 33 | func (list *DoublyCircularLinkedList) IsPresent(key int) bool { 34 | if list.head == nil { 35 | return false 36 | } 37 | 38 | temp := list.head 39 | for temp != list.tail { 40 | if temp.value == key { 41 | return true 42 | } 43 | temp = temp.next 44 | } 45 | // Check tail node separately since the loop condition does not cover it 46 | if temp.value == key { 47 | return true 48 | } 49 | return false 50 | } 51 | 52 | func (list *DoublyCircularLinkedList) FreeList() { 53 | list.head = nil 54 | list.tail = nil 55 | list.count = 0 56 | } 57 | 58 | func (list *DoublyCircularLinkedList) Print() { 59 | if list.IsEmpty() { 60 | return 61 | } 62 | 63 | temp := list.head 64 | for temp != list.tail { 65 | fmt.Print(temp.value, " ") 66 | temp = temp.next 67 | } 68 | fmt.Println(temp.value) 69 | } 70 | 71 | func (list *DoublyCircularLinkedList) AddHead(value int) { 72 | newNode := &DCListNode{value: value} 73 | if list.count == 0 { 74 | list.tail = newNode 75 | list.head = newNode 76 | newNode.next = newNode 77 | newNode.prev = newNode 78 | } else { 79 | newNode.next = list.head 80 | newNode.prev = list.head.prev 81 | list.head.prev = newNode 82 | newNode.prev.next = newNode 83 | list.head = newNode 84 | } 85 | list.count++ 86 | } 87 | 88 | func (list *DoublyCircularLinkedList) AddTail(value int) { 89 | newNode := &DCListNode{value: value} 90 | if list.count == 0 { 91 | list.head = newNode 92 | list.tail = newNode 93 | newNode.next = newNode 94 | newNode.prev = newNode 95 | } else { 96 | newNode.next = list.tail.next 97 | newNode.prev = list.tail 98 | list.tail.next = newNode 99 | newNode.next.prev = newNode 100 | list.tail = newNode 101 | } 102 | list.count++ 103 | } 104 | 105 | func (list *DoublyCircularLinkedList) RemoveHead() (int, bool) { 106 | if list.count == 0 { 107 | fmt.Println("EmptyListException") 108 | return 0, false 109 | } 110 | 111 | value := list.head.value 112 | list.count-- 113 | 114 | if list.count == 0 { 115 | list.head = nil 116 | list.tail = nil 117 | return value, true 118 | } 119 | 120 | next := list.head.next 121 | next.prev = list.tail 122 | list.tail.next = next 123 | list.head = next 124 | return value, true 125 | } 126 | 127 | func (list *DoublyCircularLinkedList) RemoveTail() (int, bool) { 128 | if list.count == 0 { 129 | fmt.Println("EmptyListException") 130 | return 0, false 131 | } 132 | 133 | value := list.tail.value 134 | list.count-- 135 | if list.count == 0 { 136 | list.head = nil 137 | list.tail = nil 138 | return value, true 139 | } 140 | 141 | prev := list.tail.prev 142 | prev.next = list.head 143 | list.head.prev = prev 144 | list.tail = prev 145 | return value, true 146 | } 147 | 148 | func main1() { 149 | ll := &DoublyCircularLinkedList{} 150 | ll.AddHead(1) 151 | ll.AddHead(2) 152 | ll.AddHead(3) 153 | ll.Print() 154 | fmt.Println("Size:", ll.Size()) 155 | fmt.Println("IsEmpty:", ll.IsEmpty()) 156 | } 157 | 158 | /* 159 | Output: 160 | 3 2 1 161 | Size: 3 162 | IsEmpty: false 163 | */ 164 | 165 | func main2() { 166 | ll := &DoublyCircularLinkedList{} 167 | ll.AddTail(1) 168 | ll.AddTail(2) 169 | ll.AddTail(3) 170 | ll.Print() 171 | } 172 | 173 | /* 174 | Output: 175 | 1 2 3 176 | */ 177 | 178 | func main3() { 179 | ll := &DoublyCircularLinkedList{} 180 | ll.AddHead(1) 181 | ll.AddHead(2) 182 | ll.AddHead(3) 183 | ll.Print() 184 | fmt.Println("IsPresent:", ll.IsPresent(3)) 185 | } 186 | 187 | /* 188 | Output: 189 | 3 2 1 190 | IsPresent: true 191 | */ 192 | 193 | func main4() { 194 | ll := &DoublyCircularLinkedList{} 195 | ll.AddHead(1) 196 | ll.AddHead(2) 197 | ll.AddHead(3) 198 | ll.Print() 199 | ll.RemoveHead() 200 | ll.Print() 201 | } 202 | 203 | /* 204 | Output: 205 | 3 2 1 206 | 2 1 207 | */ 208 | 209 | func main5() { 210 | ll := &DoublyCircularLinkedList{} 211 | ll.AddHead(1) 212 | ll.AddHead(2) 213 | ll.AddHead(3) 214 | ll.Print() 215 | ll.RemoveTail() 216 | ll.Print() 217 | } 218 | 219 | /* 220 | Output: 221 | 3 2 1 222 | 3 2 223 | */ 224 | 225 | func main() { 226 | main1() 227 | main2() 228 | main3() 229 | main4() 230 | main5() 231 | } 232 | -------------------------------------------------------------------------------- /LinkedLIst/Polynomial.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type Polynomial struct { 9 | head *Node 10 | tail *Node 11 | } 12 | 13 | type Node struct { 14 | coeff int 15 | pow int 16 | next *Node 17 | } 18 | 19 | func newNode(c int, p int) *Node { 20 | var nd = new(Node) 21 | nd.coeff = c 22 | nd.pow = p 23 | nd.next = nil 24 | return nd 25 | } 26 | 27 | func newPolynomial() *Polynomial { 28 | var poly *Polynomial = &Polynomial{} 29 | poly.head = nil 30 | poly.tail = nil 31 | return poly 32 | } 33 | 34 | func (this *Polynomial) assign(coeffs []int, pows []int, size int) *Polynomial { 35 | this.head = nil 36 | this.tail = nil 37 | var temp *Node = nil 38 | for i := 0; i < size; i++ { 39 | temp = newNode(coeffs[i], pows[i]) 40 | if this.head == nil { 41 | this.head = temp 42 | this.tail = temp 43 | } else { 44 | this.tail.next = temp 45 | this.tail = temp 46 | } 47 | } 48 | return this 49 | } 50 | 51 | func (this *Polynomial) add(poly2 *Polynomial) *Polynomial { 52 | var p1 *Node = this.head 53 | var p2 *Node = poly2.head 54 | var temp *Node = nil 55 | var poly *Polynomial = newPolynomial() 56 | for p1 != nil || p2 != nil { 57 | if p1 == nil || (p2 != nil && p1.pow < p2.pow) { 58 | temp = newNode(p2.coeff, p2.pow) 59 | p2 = p2.next 60 | } else if p2 == nil || p1.pow > p2.pow { 61 | temp = newNode(p1.coeff, p1.pow) 62 | p1 = p1.next 63 | } else if p1.pow == p2.pow { 64 | temp = newNode(p1.coeff+p2.coeff, p1.pow) 65 | p1 = p1.next 66 | p2 = p2.next 67 | } 68 | if poly.head == nil { 69 | poly.head = temp 70 | poly.tail = temp 71 | } else { 72 | poly.tail.next = temp 73 | poly.tail = poly.tail.next 74 | } 75 | } 76 | return poly 77 | } 78 | 79 | func (this *Polynomial) print() { 80 | var curr *Node = this.head 81 | for curr != nil { 82 | fmt.Print(strconv.Itoa(curr.coeff) + "x^" + strconv.Itoa(curr.pow)) 83 | if curr.next != nil { 84 | fmt.Print(" + ") 85 | } 86 | curr = curr.next 87 | } 88 | fmt.Println() 89 | } 90 | 91 | func main() { 92 | var c1 = []int{6, 5, 4} 93 | var p1 = []int{2, 1, 0} 94 | var s1 int = len(c1) 95 | var first *Polynomial = newPolynomial().assign(c1, p1, s1) 96 | first.print() 97 | 98 | var c2 = []int{3, 2, 1} 99 | var p2 = []int{3, 1, 0} 100 | var s2 int = len(c2) 101 | var second *Polynomial = newPolynomial().assign(c2, p2, s2) 102 | second.print() 103 | 104 | var sum *Polynomial = first.add(second) 105 | sum.print() 106 | } 107 | 108 | /* 109 | 6x^2 + 5x^1 + 4x^0 110 | 3x^3 + 2x^1 + 1x^0 111 | 3x^3 + 6x^2 + 7x^1 + 5x^0 112 | */ 113 | -------------------------------------------------------------------------------- /Queue/Queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Queue struct { 6 | que []interface{} 7 | } 8 | 9 | func (q *Queue) Add(value interface{}) { 10 | q.que = append(q.que, value) 11 | } 12 | 13 | func (q *Queue) Remove() interface{} { 14 | value := q.que[0] 15 | q.que = q.que[1:] 16 | return value 17 | } 18 | 19 | func (q *Queue) RemoveBack() interface{} { 20 | n := len(q.que) 21 | value := q.que[n-1] 22 | q.que = q.que[:n-1] 23 | return value 24 | } 25 | 26 | func (q *Queue) Front() interface{} { 27 | return q.que[0] 28 | } 29 | 30 | func (q *Queue) Back() interface{} { 31 | n := len(q.que) 32 | return q.que[n-1] 33 | } 34 | 35 | func (q *Queue) IsEmpty() bool { 36 | return len(q.que) == 0 37 | } 38 | 39 | func (q *Queue) Len() int { 40 | return len(q.que) 41 | } 42 | 43 | func (q *Queue) Print() { 44 | fmt.Println(q.que) 45 | } 46 | 47 | func main() { 48 | queue := new(Queue) 49 | queue.Add(1) 50 | queue.Add(2) 51 | queue.Add(3) 52 | fmt.Println("IsEmpty:", queue.IsEmpty()) 53 | fmt.Println("Size:", queue.Len()) 54 | fmt.Println("Queue remove:", queue.Remove()) 55 | fmt.Println("Queue remove:", queue.Remove()) 56 | } 57 | 58 | /* 59 | Output: 60 | IsEmpty: false 61 | Size: 3 62 | Queue remove: 1 63 | Queue remove: 2 64 | */ 65 | -------------------------------------------------------------------------------- /Queue/QueueLL.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Node struct { 6 | value int 7 | next *Node 8 | } 9 | 10 | type QueueLinkedList struct { 11 | tail *Node 12 | size int 13 | } 14 | 15 | // Size returns the number of elements in the queue. 16 | func (q *QueueLinkedList) Size() int { 17 | return q.size 18 | } 19 | 20 | // IsEmpty checks if the queue is empty. 21 | func (q *QueueLinkedList) IsEmpty() bool { 22 | return q.size == 0 23 | } 24 | 25 | // Peek returns the element at the front of the queue without removing it. 26 | func (q *QueueLinkedList) Peek() int { 27 | if q.IsEmpty() { 28 | fmt.Println("QueueEmptyException") 29 | return 0 30 | } 31 | return q.tail.next.value 32 | } 33 | 34 | // Add adds an element to the rear of the queue. 35 | func (q *QueueLinkedList) Add(value int) { 36 | temp := &Node{value, nil} 37 | if q.tail == nil { 38 | // If the queue is empty, set the tail to the new node and make it circular. 39 | q.tail = temp 40 | temp.next = temp 41 | } else { 42 | // Add the new node to the rear and update the tail. 43 | temp.next = q.tail.next 44 | q.tail.next = temp 45 | q.tail = temp 46 | } 47 | q.size++ 48 | } 49 | 50 | // Remove removes and returns the element at the front of the queue. 51 | func (q *QueueLinkedList) Remove() int { 52 | if q.IsEmpty() { 53 | fmt.Println("QueueEmptyException") 54 | return 0 55 | } 56 | 57 | // Remove the node at the front and update the tail if necessary. 58 | value := q.tail.next.value 59 | if q.tail == q.tail.next { 60 | q.tail = nil 61 | } else { 62 | q.tail.next = q.tail.next.next 63 | } 64 | q.size-- 65 | return value 66 | } 67 | 68 | // Print prints the elements in the queue. 69 | func (q *QueueLinkedList) Print() { 70 | if q.IsEmpty() { 71 | return 72 | } 73 | temp := q.tail.next 74 | for temp != q.tail { 75 | fmt.Print(temp.value, " ") 76 | temp = temp.next 77 | } 78 | fmt.Println(temp.value) 79 | } 80 | 81 | func main() { 82 | que := new(QueueLinkedList) 83 | que.Add(1) 84 | que.Add(2) 85 | que.Add(3) 86 | fmt.Println("IsEmpty:", que.IsEmpty()) 87 | fmt.Println("Size:", que.Size()) 88 | fmt.Println("Queue remove:", que.Remove()) 89 | fmt.Println("Queue remove:", que.Remove()) 90 | } 91 | 92 | /* 93 | IsEmpty: false 94 | Size: 3 95 | Queue remove: 1 96 | Queue remove: 2 97 | */ 98 | -------------------------------------------------------------------------------- /Queue/QueueLinkedLIst.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | ) 7 | 8 | type Queue struct { 9 | que *list.List 10 | } 11 | 12 | func NewQueue() *Queue { 13 | q := new(Queue) 14 | q.que = list.New() 15 | return q 16 | } 17 | 18 | func (q *Queue) Add(value interface{}) { 19 | q.que.PushBack(value) 20 | } 21 | 22 | func (q *Queue) Remove() interface{} { 23 | front := q.que.Front() 24 | val := front.Value 25 | q.que.Remove(front) 26 | return val 27 | } 28 | 29 | func (q *Queue) Front() interface{} { 30 | return q.que.Front().Value 31 | } 32 | 33 | func (q Queue) Len() int { 34 | return q.que.Len() 35 | } 36 | 37 | func (q Queue) IsEmpty() bool { 38 | return q.que.Len() == 0 39 | } 40 | 41 | func main() { 42 | q := NewQueue() 43 | for i := 0; i < 5; i++ { 44 | q.Add(i) 45 | } 46 | 47 | for q.IsEmpty() == false { 48 | val := q.Remove() 49 | fmt.Print(val, " ") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Queue/QueueUsingStack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type QueueUsingStack struct { 6 | stk1 Stack 7 | stk2 Stack 8 | } 9 | 10 | // Add adds an element to the queue. 11 | func (que *QueueUsingStack) Add(value int) { 12 | que.stk1.Push(value) 13 | } 14 | 15 | // Remove removes and returns the element at the front of the queue. 16 | func (que *QueueUsingStack) Remove() int { 17 | var value int 18 | if que.stk2.IsEmpty() == false { 19 | value = que.stk2.Pop().(int) 20 | return value 21 | } 22 | 23 | // Move elements from stk1 to stk2 to reverse the order. 24 | for que.stk1.IsEmpty() == false { 25 | value = que.stk1.Pop().(int) 26 | que.stk2.Push(value) 27 | } 28 | 29 | value = que.stk2.Pop().(int) 30 | return value 31 | } 32 | 33 | // Length returns the number of elements in the queue. 34 | func (que *QueueUsingStack) Length() int { 35 | return que.stk1.Len() + que.stk2.Len() 36 | } 37 | 38 | // IsEmpty checks if the queue is empty. 39 | func (que *QueueUsingStack) IsEmpty() bool { 40 | return que.Length() == 0 41 | } 42 | 43 | func main() { 44 | que := new(QueueUsingStack) 45 | que.Add(1) 46 | que.Add(2) 47 | que.Add(3) 48 | fmt.Println(que.Length()) 49 | fmt.Println(que.IsEmpty()) 50 | fmt.Println(que.Remove()) 51 | fmt.Println(que.Remove()) 52 | fmt.Println(que.Remove()) 53 | fmt.Println(que.IsEmpty()) 54 | } 55 | 56 | /* 57 | 3 58 | false 59 | 1 60 | 2 61 | 3 62 | true 63 | */ 64 | 65 | type Stack struct { 66 | stk []interface{} 67 | } 68 | 69 | // Push adds an element to the top of the stack. 70 | func (s *Stack) Push(data interface{}) { 71 | s.stk = append(s.stk, data) 72 | } 73 | 74 | // Pop removes and returns the element at the top of the stack. 75 | func (s *Stack) Pop() interface{} { 76 | n := len(s.stk) 77 | value := s.stk[n-1] 78 | s.stk = s.stk[:n-1] 79 | return value 80 | } 81 | 82 | // Top returns the element at the top of the stack without removing it. 83 | func (s *Stack) Top() interface{} { 84 | n := len(s.stk) 85 | return s.stk[n-1] 86 | } 87 | 88 | // Len returns the number of elements in the stack. 89 | func (s Stack) Len() int { 90 | return len(s.stk) 91 | } 92 | 93 | // IsEmpty checks if the stack is empty. 94 | func (s Stack) IsEmpty() bool { 95 | return len(s.stk) == 0 96 | } 97 | 98 | // Print prints the elements in the stack. 99 | func (s Stack) Print() { 100 | fmt.Println(s.stk) 101 | } 102 | -------------------------------------------------------------------------------- /Queue/StackUsingQueue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type StackUsingQueue struct { 6 | que1 Queue 7 | que2 Queue 8 | size int 9 | } 10 | 11 | // Push adds an element to the stack. 12 | func (stk *StackUsingQueue) Push(value int) { 13 | stk.que1.Add(value) 14 | stk.size++ 15 | } 16 | 17 | // Pop removes and returns the element at the top of the stack. 18 | func (stk *StackUsingQueue) Pop() int { 19 | var value int 20 | s := stk.que1.Length() 21 | for s > 0 { 22 | value = stk.que1.Remove().(int) 23 | if s > 1 { 24 | stk.que2.Add(value) 25 | } 26 | s-- 27 | } 28 | temp := stk.que1 29 | stk.que1 = stk.que2 30 | stk.que2 = temp 31 | stk.size-- 32 | return value 33 | } 34 | 35 | // Pop2 removes and returns the element at the top of the stack. 36 | func (stk *StackUsingQueue) Pop2() int { 37 | var value int 38 | s := stk.que1.Length() 39 | for s > 0 { 40 | value = stk.que1.Remove().(int) 41 | if s > 1 { 42 | stk.que1.Add(value) 43 | } 44 | s-- 45 | } 46 | stk.size-- 47 | return value 48 | } 49 | 50 | func main1() { 51 | stk := new(StackUsingQueue) 52 | stk.Push(1) 53 | stk.Push(2) 54 | stk.Push(3) 55 | fmt.Println("Stack pop:", stk.Pop()) 56 | fmt.Println("Stack pop:", stk.Pop()) 57 | } 58 | 59 | func main2() { 60 | stk := new(StackUsingQueue) 61 | stk.Push(1) 62 | stk.Push(2) 63 | stk.Push(3) 64 | fmt.Println("Stack pop:", stk.Pop2()) 65 | fmt.Println("Stack pop:", stk.Pop2()) 66 | } 67 | 68 | func main() { 69 | main1() 70 | main2() 71 | } 72 | 73 | /* 74 | Stack pop: 3 75 | Stack pop: 2 76 | 77 | 78 | Stack pop: 3 79 | Stack pop: 2 80 | 81 | */ 82 | 83 | type Queue struct { 84 | que []interface{} 85 | } 86 | 87 | // Add adds an element to the queue. 88 | func (q *Queue) Add(value interface{}) { 89 | q.que = append(q.que, value) 90 | } 91 | 92 | // Remove removes and returns the element at the front of the queue. 93 | func (q *Queue) Remove() interface{} { 94 | n := len(q.que) 95 | value := q.que[0] 96 | q.que = q.que[1:n] 97 | return value 98 | } 99 | 100 | // RemoveBack removes and returns the element at the back of the queue. 101 | func (q *Queue) RemoveBack() interface{} { 102 | n := len(q.que) 103 | value := q.que[n-1] 104 | q.que = q.que[:n-1] 105 | return value 106 | } 107 | 108 | // Front returns the element at the front of the queue without removing it. 109 | func (q *Queue) Front() interface{} { 110 | return q.que[0] 111 | } 112 | 113 | // Back returns the element at the back of the queue without removing it. 114 | func (q *Queue) Back() interface{} { 115 | n := len(q.que) 116 | return q.que[n-1] 117 | } 118 | 119 | // IsEmpty checks if the queue is empty. 120 | func (q *Queue) IsEmpty() bool { 121 | return len(q.que) == 0 122 | } 123 | 124 | // Length returns the number of elements in the queue. 125 | func (q *Queue) Length() int { 126 | return len(q.que) 127 | } 128 | 129 | // Print prints the elements in the queue. 130 | func (q Queue) Print() { 131 | fmt.Println(q.que) 132 | } 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-Structures-Algorithms-In-Go 2 | 3 | **This is the code repository of book "Data Structures & Algorithms in Go".** 4 | 5 | ![alt text](https://m.media-amazon.com/images/P/B0BL3NFD78.jpg) 6 | 7 | 8 | **About The Book** 9 | - This textbook provides in depth coverage of various Data Structures and Algorithms. 10 | - Concepts are discussed in easy to understand manner. 11 | - Large number of diagrams are provided to grasp concepts easily. 12 | - Time and Space complexities of various algorithms are discussed. 13 | - Helpful for interviews preparation and competitive coding. 14 | - Large number of interview questions are solved. 15 | - Go solutions are provided with input and output. 16 | - Guide you through how to solve new problems in programming interview of various software companies. 17 | 18 | 19 | **Table of Contents** 20 | - Chapter 0: How to use this book. 21 | - Chapter 1: Algorithms Analysis 22 | - Chapter 2: Approach to solve algorithm design problems 23 | - Chapter 3: Abstract Data Type & Go Collections 24 | - Chapter 4: Searching 25 | - Chapter 5: Sorting 26 | - Chapter 6: Linked List 27 | - Chapter 7: Stack 28 | - Chapter 8: Queue 29 | - Chapter 9: Tree 30 | - Chapter 10: Priority Queue 31 | - Chapter 11: Hash-Table 32 | - Chapter 12: Graphs 33 | - Chapter 13: String Algorithms 34 | - Chapter 14: Algorithm Design Techniques 35 | - Chapter 15: Brute Force Algorithm 36 | - Chapter 16: Greedy Algorithm 37 | - Chapter 17: Divide & Conquer 38 | - Chapter 18: Dynamic Programming 39 | - Chapter 19: Backtracking 40 | - Chapter 20: Complexity Theory 41 | 42 | -------------------------------------------------------------------------------- /Searching/BitManipulation.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func AndEx(a int, b int) int { 6 | return a & b 7 | } 8 | 9 | func BitReversalEx(a int) int { 10 | return -a - 1 11 | } 12 | 13 | func CountBits(a int) int { 14 | count := 0 15 | for a > 0 { 16 | count += 1 17 | a = a & (a - 1) 18 | } 19 | return count 20 | } 21 | 22 | func IsPowerOf2(a int) bool { 23 | if a&(a-1) == 0 { 24 | return true 25 | } else { 26 | return false 27 | } 28 | } 29 | 30 | func KthBitCheck(a int, k int) bool { 31 | return a&(1<<(k-1)) > 0 32 | } 33 | 34 | func KthBitReset(a int, k int) int { 35 | return a & ^(1 << (k - 1)) 36 | } 37 | 38 | func KthBitSet(a int, k int) int { 39 | return a | 1<<(k-1) 40 | } 41 | 42 | func KthBitToggle(a int, k int) int { 43 | return a ^ 1<<(k-1) 44 | } 45 | 46 | func LeftShiftEx(a int) int { 47 | return a << 1 48 | } 49 | 50 | func OrEx(a int, b int) int { 51 | return a | b 52 | } 53 | 54 | func ResetRightMostBit(a int) int { 55 | return a & (a - 1) 56 | } 57 | 58 | func RightMostBit(a int) int { 59 | return a & -a 60 | } 61 | 62 | func RightShiftEx(a int) int { 63 | return a >> 1 64 | } 65 | 66 | func TwoComplementEx(a int) int { 67 | return -a 68 | } 69 | 70 | func XorEx(a int, b int) int { 71 | return a ^ b 72 | } 73 | 74 | func main() { 75 | a := 4 76 | b := 8 77 | fmt.Println(AndEx(a, b)) 78 | fmt.Println(OrEx(a, b)) 79 | fmt.Println(XorEx(a, b)) 80 | fmt.Println(LeftShiftEx(a)) // multiply by 2 81 | fmt.Println(RightShiftEx(a)) // divide by 2 82 | fmt.Println(BitReversalEx(a)) 83 | fmt.Println(TwoComplementEx(a)) 84 | fmt.Println(KthBitCheck(a, 3)) 85 | fmt.Println(KthBitSet(a, 2)) 86 | fmt.Println(KthBitReset(a, 3)) 87 | fmt.Println(KthBitToggle(a, 3)) 88 | fmt.Println(RightMostBit(a)) 89 | fmt.Println(ResetRightMostBit(a)) 90 | fmt.Println(IsPowerOf2(a)) 91 | for i := 0; i < 10; i++ { 92 | fmt.Println(i, " bit count : ", CountBits(i)) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Sorting/BubbleSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func less(value1, value2 int) bool { 8 | return value1 < value2 9 | } 10 | 11 | func greater(value1, value2 int) bool { 12 | return value1 > value2 13 | } 14 | 15 | // BubbleSort sorts the array using the specified comparison function. 16 | func BubbleSort(arr []int, comp func(int, int) bool) { 17 | size := len(arr) 18 | for i := 0; i < size-1; i++ { 19 | for j := 0; j < size-i-1; j++ { 20 | if comp(arr[j], arr[j+1]) { 21 | // Swapping 22 | arr[j+1], arr[j] = arr[j], arr[j+1] 23 | } 24 | } 25 | } 26 | } 27 | 28 | // BubbleSort2 sorts the array using the specified comparison function. 29 | // It includes an optimization to stop early if no swaps are made in a pass. 30 | func BubbleSort2(arr []int, comp func(int, int) bool) { 31 | size := len(arr) 32 | swapped := true 33 | for i := 0; i < size-1 && swapped; i++ { 34 | swapped = false 35 | for j := 0; j < size-i-1; j++ { 36 | if comp(arr[j], arr[j+1]) { 37 | arr[j+1], arr[j] = arr[j], arr[j+1] 38 | swapped = true 39 | } 40 | } 41 | } 42 | } 43 | 44 | func main() { 45 | data := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 46 | BubbleSort(data, greater) 47 | fmt.Println(data) 48 | 49 | data3 := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 50 | BubbleSort(data3, less) 51 | fmt.Println(data3) 52 | 53 | data2 := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 54 | BubbleSort2(data2, less) 55 | fmt.Println(data2) 56 | } 57 | 58 | /* 59 | [1 2 3 4 5 6 7 8 9] 60 | [9 8 7 6 5 4 3 2 1] 61 | [9 8 7 6 5 4 3 2 1] 62 | */ 63 | -------------------------------------------------------------------------------- /Sorting/BucketSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "sort" 7 | ) 8 | 9 | func BucketSort(arr []int, maxValue, numBucket int) { 10 | length := len(arr) 11 | if length == 0 { 12 | return 13 | } 14 | bucket := make([][]int, numBucket) 15 | div := int(math.Ceil(float64(maxValue / numBucket))) 16 | 17 | for i := 0; i < length; i++ { 18 | if arr[i] < 0 || arr[i] > maxValue { 19 | fmt.Println("Value out of range.") 20 | return 21 | } 22 | bucketIndex := arr[i] / div 23 | if bucketIndex >= numBucket { 24 | bucketIndex = numBucket - 1 25 | } 26 | bucket[bucketIndex] = append(bucket[bucketIndex], arr[i]) 27 | } 28 | for i := 0; i < numBucket; i++ { 29 | sort.Slice(bucket[i], func(a, b int) bool { 30 | return bucket[i][a] < bucket[i][b] 31 | }) 32 | } 33 | index := 0 34 | var count int 35 | for i := 0; i < numBucket; i++ { 36 | temp := bucket[i] 37 | count = len(temp) 38 | for j := 0; j < count; j++ { 39 | arr[index] = temp[j] 40 | index++ 41 | } 42 | } 43 | } 44 | 45 | // Testing code. 46 | func main() { 47 | array := []int{1, 34, 7, 99, 5, 23, 45, 88, 77, 19, 91, 100} 48 | maxValue := 100 49 | numBucket := 5 50 | BucketSort(array, maxValue, numBucket) 51 | fmt.Print(array) 52 | } 53 | 54 | // [1 5 7 19 23 34 45 77 88 91 99 100] 55 | -------------------------------------------------------------------------------- /Sorting/CountSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // CountSort performs counting sort on the given array within the specified range. 6 | func CountSort(arr []int, lowerRange int, upperRange int) { 7 | var i int 8 | var j int 9 | size := len(arr) 10 | rangeVal := upperRange - lowerRange 11 | count := make([]int, rangeVal) 12 | for i = 0; i < size; i++ { 13 | count[arr[i]-lowerRange]++ 14 | } 15 | j = 0 16 | for i = 0; i < rangeVal; i++ { 17 | for ; count[i] > 0; count[i]-- { 18 | arr[j] = i + lowerRange 19 | j++ 20 | } 21 | } 22 | } 23 | 24 | func main() { 25 | array := []int{23, 24, 22, 21, 26, 25, 27, 28, 21, 21} 26 | CountSort(array, 20, 30) 27 | fmt.Print(array) 28 | } 29 | 30 | // [21 21 21 22 23 24 25 26 27 28] 31 | -------------------------------------------------------------------------------- /Sorting/InsertionSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | data := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 7 | InsertionSort(data, greater) 8 | fmt.Println(data) 9 | } 10 | 11 | func less(value1 int, value2 int) bool { 12 | return value1 < value2 13 | } 14 | 15 | func greater(value1 int, value2 int) bool { 16 | return value1 > value2 17 | } 18 | 19 | func InsertionSort(arr []int, comp func(int, int) bool) { 20 | size := len(arr) 21 | var temp, i, j int 22 | for i = 1; i < size; i++ { 23 | temp = arr[i] 24 | for j = i; j > 0 && comp(arr[j-1], temp); j-- { 25 | arr[j] = arr[j-1] 26 | } 27 | arr[j] = temp 28 | } 29 | } 30 | 31 | /* 32 | [1 2 3 4 5 6 7 8 9] 33 | */ 34 | -------------------------------------------------------------------------------- /Sorting/MergeSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func MergeSort(arr []int) { 6 | size := len(arr) 7 | tempArray := make([]int, size) 8 | mergeSort(arr, tempArray, 0, size-1) 9 | } 10 | 11 | func mergeSort(arr []int, tempArray []int, lowerIndex int, upperIndex int) { 12 | if lowerIndex >= upperIndex { 13 | return 14 | } 15 | middleIndex := (lowerIndex + upperIndex) / 2 16 | mergeSort(arr, tempArray, lowerIndex, middleIndex) 17 | mergeSort(arr, tempArray, middleIndex+1, upperIndex) 18 | merge(arr, tempArray, lowerIndex, middleIndex, upperIndex) 19 | } 20 | 21 | func merge(arr []int, tempArray []int, lowerIndex int, middleIndex int, upperIndex int) { 22 | lowerStart := lowerIndex 23 | lowerStop := middleIndex 24 | upperStart := middleIndex + 1 25 | upperStop := upperIndex 26 | count := lowerIndex 27 | for lowerStart <= lowerStop && upperStart <= upperStop { 28 | if arr[lowerStart] < arr[upperStart] { 29 | tempArray[count] = arr[lowerStart] 30 | lowerStart++ 31 | } else { 32 | tempArray[count] = arr[upperStart] 33 | upperStart++ 34 | } 35 | count++ 36 | } 37 | for lowerStart <= lowerStop { 38 | tempArray[count] = arr[lowerStart] 39 | count++ 40 | lowerStart++ 41 | } 42 | for upperStart <= upperStop { 43 | tempArray[count] = arr[upperStart] 44 | count++ 45 | upperStart++ 46 | } 47 | for i := lowerIndex; i <= upperIndex; i++ { 48 | arr[i] = tempArray[i] 49 | } 50 | } 51 | 52 | func main() { 53 | data := []int{3, 4, 2, 1, 6, 5, 7, 8} 54 | MergeSort(data) 55 | fmt.Println(data) 56 | } 57 | 58 | /* 59 | [1 2 3 4 5 6 7 8] 60 | */ 61 | -------------------------------------------------------------------------------- /Sorting/QuickSelect.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func QuickSelect(arr []int, key int) int { 6 | size := len(arr) 7 | quickSelectUtil(arr, 0, size-1, key-1) 8 | return arr[key-1] 9 | } 10 | 11 | func quickSelectUtil(arr []int, lower int, upper int, key int) { 12 | if upper <= lower { 13 | return 14 | } 15 | pivot := arr[lower] 16 | start := lower 17 | stop := upper 18 | 19 | for lower < upper { 20 | for arr[lower] <= pivot && lower < upper { 21 | lower++ 22 | } 23 | for arr[upper] > pivot && lower <= upper { 24 | upper-- 25 | } 26 | if lower < upper { 27 | swap(arr, upper, lower) 28 | } 29 | } 30 | swap(arr, upper, start) // upper is the pivot position 31 | quickSelectUtil(arr, start, upper-1, key) // pivot -1 is the upper for left sub array. 32 | quickSelectUtil(arr, upper+1, stop, key) // pivot + 1 is the lower for right sub array. 33 | } 34 | 35 | func swap(arr []int, first int, second int) { 36 | arr[first], arr[second] = arr[second], arr[first] 37 | } 38 | 39 | func main() { 40 | data := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 41 | fmt.Println("Fifth value is :", QuickSelect(data, 5)) 42 | } 43 | 44 | /* 45 | Fifth value is : 5 46 | */ 47 | -------------------------------------------------------------------------------- /Sorting/QuickSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func QuickSort(arr []int) { 6 | size := len(arr) 7 | quickSortUtil(arr, 0, size-1) 8 | } 9 | 10 | func quickSortUtil(arr []int, lower int, upper int) { 11 | if upper <= lower { 12 | return 13 | } 14 | pivot := arr[lower] 15 | start := lower 16 | stop := upper 17 | 18 | for lower < upper { 19 | for arr[lower] <= pivot && lower < upper { 20 | lower++ 21 | } 22 | for arr[upper] > pivot && lower <= upper { 23 | upper-- 24 | } 25 | if lower < upper { 26 | swap(arr, upper, lower) 27 | } 28 | } 29 | swap(arr, upper, start) // upper is the pivot position 30 | quickSortUtil(arr, start, upper-1) // pivot -1 is the upper for left sub array. 31 | quickSortUtil(arr, upper+1, stop) // pivot + 1 is the lower for right sub array. 32 | } 33 | 34 | func swap(arr []int, first int, second int) { 35 | arr[first], arr[second] = arr[second], arr[first] 36 | } 37 | 38 | func main() { 39 | data := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 40 | QuickSort(data) 41 | fmt.Println(data) 42 | } 43 | -------------------------------------------------------------------------------- /Sorting/RadixSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func RadixSort(arr []int) { 6 | n := len(arr) 7 | m := getMax(arr, n) 8 | // Counting sort for every digit. 9 | // The dividend passed is used to calculate current working digit. 10 | for div := 1; m/div > 0; div *= 10 { 11 | countSort(arr, n, div) 12 | } 13 | } 14 | 15 | func getMax(arr []int, n int) int { 16 | max := arr[0] 17 | for i := 1; i < n; i++ { 18 | if max < arr[i] { 19 | max = arr[i] 20 | } 21 | } 22 | return max 23 | } 24 | 25 | func countSort(arr []int, n int, dividend int) { 26 | temp := make([]int, n) 27 | copy(temp, arr) 28 | 29 | // Store count of occurrences in count array. 30 | // (number / dividend) % 10 is used to find the working digit. 31 | count := make([]int, 10) 32 | for i := 0; i < n; i++ { 33 | count[(temp[i]/dividend)%10]++ 34 | } 35 | 36 | // Change count[i] so that count[i] contains 37 | // number of elements till index i in output. 38 | for i := 1; i < 10; i++ { 39 | count[i] += count[i-1] 40 | } 41 | 42 | // Copy content to input arr. 43 | for i := n - 1; i >= 0; i-- { 44 | arr[count[(temp[i]/dividend)%10]-1] = temp[i] 45 | count[(temp[i]/dividend)%10]-- 46 | } 47 | } 48 | 49 | func main() { 50 | array := []int{100, 49, 65, 91, 702, 29, 4, 55} 51 | RadixSort(array) 52 | fmt.Println(array) 53 | } 54 | 55 | /* 56 | [4 29 49 55 65 91 100 702] 57 | */ 58 | -------------------------------------------------------------------------------- /Sorting/SelectionSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | data := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 9 | SelectionSort(data) 10 | fmt.Println(data) 11 | 12 | data2 := []int{9, 1, 8, 2, 7, 3, 6, 4, 5} 13 | SelectionSort2(data2) 14 | fmt.Println(data2) 15 | } 16 | 17 | /* 18 | [1 2 3 4 5 6 7 8 9] 19 | [1 2 3 4 5 6 7 8 9] 20 | 21 | */ 22 | 23 | func SelectionSort(arr []int) { 24 | size := len(arr) 25 | for i := 0; i < size; i++ { 26 | max := 0 27 | for j := 1; j < size-i; j++ { 28 | if arr[j] > arr[max] { 29 | max = j 30 | } 31 | } 32 | arr[size-1-i], arr[max] = arr[max], arr[size-1-i] 33 | } 34 | } 35 | 36 | func SelectionSort2(arr []int) { 37 | size := len(arr) 38 | for i := 0; i < size-1; i++ { 39 | min := i 40 | for j := i + 1; j < size; j++ { 41 | if arr[j] < arr[min] { 42 | min = j 43 | } 44 | } 45 | arr[i], arr[min] = arr[min], arr[i] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sorting/ShellSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func greater(value1 int, value2 int) bool { 6 | return value1 > value2 7 | } 8 | 9 | func ShellSort(arr []int) { 10 | n := len(arr) 11 | // Gap starts with n/2 and half in each iteration. 12 | for gap := n / 2; gap > 0; gap /= 2 { 13 | // Do a gapped insertion sort. 14 | for i := gap; i < n; i += 1 { 15 | curr := arr[i] 16 | // Shift elements of already sorted list 17 | // to find right position for curr value. 18 | var j int 19 | for j = i; j >= gap && greater(arr[j-gap], curr); j -= gap { 20 | arr[j] = arr[j-gap] 21 | } 22 | // Put current value in its correct location 23 | arr[j] = curr 24 | } 25 | } 26 | } 27 | 28 | // Testing code. 29 | func main() { 30 | array := []int{36, 32, 11, 6, 19, 31, 17, 3} 31 | ShellSort(array) 32 | fmt.Print(array) 33 | } 34 | 35 | // [3 6 11 17 19 31 32 36] 36 | -------------------------------------------------------------------------------- /Stack/Stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Stack struct { 6 | stk []interface{} 7 | } 8 | 9 | func (s *Stack) Push(data interface{}) { 10 | s.stk = append(s.stk, data) 11 | } 12 | 13 | func (s *Stack) Pop() interface{} { 14 | n := len(s.stk) 15 | value := s.stk[n-1] 16 | s.stk = s.stk[:n-1] 17 | return value 18 | } 19 | 20 | func (s *Stack) Top() interface{} { 21 | n := len(s.stk) 22 | return s.stk[n-1] 23 | } 24 | 25 | func (s Stack) Len() int { 26 | return len(s.stk) 27 | } 28 | 29 | func (s Stack) IsEmpty() bool { 30 | return len(s.stk) == 0 31 | } 32 | 33 | func (s Stack) Print() { 34 | fmt.Println(s.stk) 35 | } 36 | 37 | func main() { 38 | stk := &Stack{} 39 | stk.Push(1) 40 | stk.Push(2) 41 | stk.Push(3) 42 | stk.Print() 43 | fmt.Print(stk.Pop(), " ") 44 | fmt.Print(stk.Pop(), " ") 45 | } 46 | 47 | /* 48 | Output: 49 | [1 2 3] 50 | 3 2 51 | */ 52 | -------------------------------------------------------------------------------- /Stack/StackLL.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Node struct { 6 | value int 7 | next *Node 8 | } 9 | 10 | type StackLinkedList struct { 11 | head *Node 12 | size int 13 | } 14 | 15 | func (s *StackLinkedList) Size() int { 16 | return s.size 17 | } 18 | 19 | func (s *StackLinkedList) IsEmpty() bool { 20 | return s.size == 0 21 | } 22 | 23 | func (s *StackLinkedList) Peek() int { 24 | if s.IsEmpty() { 25 | fmt.Println("StackEmptyException") 26 | return 0 27 | } 28 | return s.head.value 29 | } 30 | 31 | func (s *StackLinkedList) Push(value int) { 32 | s.head = &Node{value, s.head} 33 | s.size++ 34 | } 35 | 36 | func (s *StackLinkedList) Pop() int { 37 | if s.IsEmpty() { 38 | fmt.Println("StackEmptyException") 39 | return 0 40 | } 41 | 42 | value := s.head.value 43 | s.head = s.head.next 44 | s.size-- 45 | return value 46 | } 47 | 48 | func (s *StackLinkedList) Print() { 49 | temp := s.head 50 | fmt.Print("[") 51 | for temp != nil { 52 | fmt.Print(temp.value, " ") 53 | temp = temp.next 54 | } 55 | fmt.Println("]") 56 | } 57 | 58 | func (s *StackLinkedList) InsertAtBottom(value int) { 59 | if s.IsEmpty() { 60 | s.Push(value) 61 | } else { 62 | temp := s.Pop() 63 | s.InsertAtBottom(value) 64 | s.Push(temp) 65 | } 66 | } 67 | 68 | // Testing code 69 | func main() { 70 | stk := new(StackLinkedList) 71 | stk.Push(1) 72 | stk.Push(2) 73 | stk.Push(3) 74 | stk.Print() 75 | fmt.Print(stk.Pop(), " ") 76 | fmt.Print(stk.Pop(), " ") 77 | } 78 | 79 | /* 80 | Output: 81 | [3 2 1 ] 82 | 3 2 83 | */ 84 | -------------------------------------------------------------------------------- /Stack/StackLinkedList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | ) 7 | 8 | type Stack struct { 9 | stk *list.List 10 | } 11 | 12 | func NewStack() *Stack { 13 | st := new(Stack) 14 | st.stk = list.New() 15 | return st 16 | } 17 | 18 | func (st *Stack) Push(data interface{}) { 19 | st.stk.PushBack(data) 20 | } 21 | 22 | func (st *Stack) Pop() interface{} { 23 | back := st.stk.Back() 24 | value := back.Value 25 | st.stk.Remove(back) 26 | return value 27 | } 28 | 29 | func (st *Stack) Top() interface{} { 30 | return st.stk.Back().Value 31 | } 32 | 33 | func (st Stack) Len() int { 34 | return st.stk.Len() 35 | } 36 | 37 | func (st Stack) IsEmpty() bool { 38 | return st.stk.Len() == 0 39 | } 40 | 41 | func (st Stack) Print() { 42 | for e := st.stk.Front(); e != nil; e = e.Next() { 43 | fmt.Print(e.Value, " ") 44 | } 45 | fmt.Println() 46 | } 47 | 48 | func main() { 49 | stk := NewStack() 50 | for i := 0; i < 5; i++ { 51 | stk.Push(i) 52 | } 53 | for stk.IsEmpty() == false { 54 | fmt.Print(stk.Pop(), " ") 55 | } 56 | } 57 | 58 | /* 59 | Output: 60 | 4 3 2 1 0 61 | */ 62 | -------------------------------------------------------------------------------- /String/StringMatching.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const ( 8 | prime = 101 9 | ) 10 | 11 | func BruteForceSearch(text string, pattern string) int { 12 | n := len(text) 13 | m := len(pattern) 14 | for i := 0; i <= n-m; i++ { 15 | for j := 0; j < m && pattern[j] == text[i+j]; j++ { 16 | if j == m-1 { 17 | return i 18 | } 19 | } 20 | } 21 | return -1 22 | } 23 | 24 | func RobinKarp(text string, pattern string) int { 25 | n := len(text) 26 | m := len(pattern) 27 | powm := 1 28 | TextHash := 0 29 | PatternHash := 0 30 | 31 | if m == 0 || m > n { 32 | return -1 33 | } 34 | 35 | for i := 0; i < m-1; i++ { 36 | powm = (powm << 1) % prime 37 | } 38 | 39 | for i := 0; i < m; i++ { 40 | PatternHash = ((PatternHash << 1) + int(pattern[i])) % prime 41 | TextHash = ((TextHash << 1) + int(text[i])) % prime 42 | } 43 | 44 | for i := 0; i <= (n - m); i++ { 45 | if TextHash == PatternHash { 46 | for j := 0; j < m; j++ { 47 | if text[i+j] != pattern[j] { 48 | break 49 | } 50 | if j == m-1 { 51 | return i 52 | } 53 | } 54 | } 55 | TextHash = (((TextHash - int(text[i])*powm) << 1) + int(text[i+m])) % prime 56 | if TextHash < 0 { 57 | TextHash = (TextHash + prime) 58 | } 59 | } 60 | 61 | return -1 62 | } 63 | 64 | func KMPPreprocess(pattern string, ShiftArr []int) { 65 | m := len(pattern) 66 | i := 0 67 | j := -1 68 | ShiftArr[i] = -1 69 | for i < m { 70 | for j >= 0 && pattern[i] != pattern[j] { 71 | j = ShiftArr[j] 72 | } 73 | i++ 74 | j++ 75 | ShiftArr[i] = j 76 | } 77 | } 78 | 79 | func KMP(text string, pattern string) int { 80 | n := len(text) 81 | m := len(pattern) 82 | ShiftArr := make([]int, m+1) 83 | KMPPreprocess(pattern, ShiftArr) 84 | i := 0 85 | j := 0 86 | 87 | for i < n { 88 | for j >= 0 && text[i] != pattern[j] { 89 | j = ShiftArr[j] 90 | } 91 | i++ 92 | j++ 93 | if j == m { 94 | return i - m 95 | } 96 | } 97 | 98 | return -1 99 | } 100 | 101 | func KMPFindCount(text string, pattern string) int { 102 | n := len(text) 103 | m := len(pattern) 104 | ShiftArr := make([]int, m+1) 105 | KMPPreprocess(pattern, ShiftArr) 106 | i := 0 107 | j := 0 108 | count := 0 109 | 110 | for i < n { 111 | for j >= 0 && text[i] != pattern[j] { 112 | j = ShiftArr[j] 113 | } 114 | i++ 115 | j++ 116 | if j == m { 117 | count++ 118 | j = ShiftArr[j] 119 | } 120 | } 121 | 122 | return count 123 | } 124 | 125 | func main() { 126 | text := "hello, world!" 127 | pattern := "world" 128 | fmt.Println("Using BruteForceSearch pattern found at index:", BruteForceSearch(text, pattern)) 129 | fmt.Println("Using RobinKarp pattern found at index:", RobinKarp(text, pattern)) 130 | fmt.Println("Using KMP pattern found at index:", KMP(text, pattern)) 131 | 132 | text = "Only time will tell if we stand the test of time" 133 | fmt.Println("Frequency of 'time' is", KMPFindCount(text, "time")) 134 | } 135 | 136 | /* 137 | Using BruteForceSearch pattern found at index: 7 138 | Using RobinKarp pattern found at index: 7 139 | Using KMP pattern found at index: 7 140 | Frequency of 'time' is 2 141 | */ 142 | -------------------------------------------------------------------------------- /String/StringTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type TreeNode struct { 9 | value string 10 | count int 11 | lChild *TreeNode 12 | rChild *TreeNode 13 | } 14 | 15 | type StringTree struct { 16 | root *TreeNode 17 | } 18 | 19 | func (t *StringTree) print() { 20 | t.printUtil(t.root) 21 | } 22 | 23 | func (t *StringTree) printUtil(curr *TreeNode) { 24 | if curr != nil { 25 | fmt.Println("value is:", curr.value) 26 | fmt.Println("count is:", curr.count) 27 | t.printUtil(curr.lChild) 28 | t.printUtil(curr.rChild) 29 | } 30 | } 31 | 32 | func (t *StringTree) Insert(value string) { 33 | t.root = t.insertUtil(value, t.root) 34 | } 35 | 36 | func (t *StringTree) insertUtil(value string, curr *TreeNode) *TreeNode { 37 | if curr == nil { 38 | return &TreeNode{ 39 | value: value, 40 | count: 1, 41 | } 42 | } 43 | 44 | compare := strings.Compare(curr.value, value) 45 | if compare == 0 { 46 | curr.count++ 47 | } else if compare == 1 { 48 | curr.lChild = t.insertUtil(value, curr.lChild) 49 | } else { 50 | curr.rChild = t.insertUtil(value, curr.rChild) 51 | } 52 | 53 | return curr 54 | } 55 | 56 | func (t *StringTree) freeTree() { 57 | t.root = nil 58 | } 59 | 60 | func (t *StringTree) Find(value string) bool { 61 | return t.findUtil(t.root, value) 62 | } 63 | 64 | func (t *StringTree) findUtil(curr *TreeNode, value string) bool { 65 | if curr == nil { 66 | return false 67 | } 68 | 69 | compare := strings.Compare(curr.value, value) 70 | if compare == 0 { 71 | return true 72 | } else if compare == 1 { 73 | return t.findUtil(curr.lChild, value) 74 | } else { 75 | return t.findUtil(curr.rChild, value) 76 | } 77 | } 78 | 79 | func (t *StringTree) frequency(value string) int { 80 | return t.frequencyUtil(t.root, value) 81 | } 82 | 83 | func (t *StringTree) frequencyUtil(curr *TreeNode, value string) int { 84 | if curr == nil { 85 | return 0 86 | } 87 | 88 | compare := strings.Compare(curr.value, value) 89 | if compare == 0 { 90 | return curr.count 91 | } else if compare > 0 { 92 | return t.frequencyUtil(curr.lChild, value) 93 | } else { 94 | return t.frequencyUtil(curr.rChild, value) 95 | } 96 | } 97 | 98 | // Testing code. 99 | func main() { 100 | t := &StringTree{} 101 | t.Insert("banana") 102 | t.Insert("apple") 103 | t.Insert("mango") 104 | fmt.Println("Apple Found:", t.Find("apple")) 105 | fmt.Println("Grapes Found:", t.Find("grapes")) 106 | fmt.Println("Banana Found:", t.Find("banana")) 107 | } 108 | -------------------------------------------------------------------------------- /String/TST.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type TSTNode struct { 6 | data byte 7 | isLastChar bool 8 | left, equal, right *TSTNode 9 | } 10 | 11 | type TST struct { 12 | root *TSTNode 13 | } 14 | 15 | func (t *TST) Insert(word string) { 16 | t.root = t.insertUtil(t.root, word, 0) 17 | } 18 | 19 | func (t *TST) insertUtil(currentNode *TSTNode, word string, currentIndex int) *TSTNode { 20 | if currentNode == nil { 21 | currentNode = &TSTNode{ 22 | data: word[currentIndex], 23 | } 24 | } 25 | 26 | if word[currentIndex] < currentNode.data { 27 | currentNode.left = t.insertUtil(currentNode.left, word, currentIndex) 28 | return currentNode 29 | } 30 | 31 | if word[currentIndex] > currentNode.data { 32 | currentNode.right = t.insertUtil(currentNode.right, word, currentIndex) 33 | return currentNode 34 | } 35 | 36 | if currentIndex < len(word)-1 { 37 | currentNode.equal = t.insertUtil(currentNode.equal, word, currentIndex+1) 38 | } else { 39 | currentNode.isLastChar = true 40 | } 41 | 42 | return currentNode 43 | } 44 | 45 | func (t *TST) findUtil(currentNode *TSTNode, searchWord string, currentIndex int) bool { 46 | if currentNode == nil { 47 | return false 48 | } 49 | 50 | if searchWord[currentIndex] < currentNode.data { 51 | return t.findUtil(currentNode.left, searchWord, currentIndex) 52 | } 53 | 54 | if searchWord[currentIndex] > currentNode.data { 55 | return t.findUtil(currentNode.right, searchWord, currentIndex) 56 | } 57 | 58 | if currentIndex == len(searchWord)-1 { 59 | return currentNode.isLastChar 60 | } 61 | 62 | return t.findUtil(currentNode.equal, searchWord, currentIndex+1) 63 | } 64 | 65 | func (t *TST) Find(searchWord string) bool { 66 | return t.findUtil(t.root, searchWord, 0) 67 | } 68 | 69 | // Testing code. 70 | func main() { 71 | t := new(TST) 72 | t.Insert("banana") 73 | t.Insert("apple") 74 | t.Insert("mango") 75 | fmt.Println("Apple Found:", t.Find("apple")) 76 | fmt.Println("Banana Found:", t.Find("banana")) 77 | fmt.Println("Grapes Found:", t.Find("grapes")) 78 | } 79 | 80 | /* 81 | Apple Found: true 82 | Banana Found: true 83 | Grapes Found: false 84 | */ 85 | -------------------------------------------------------------------------------- /String/Trie.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | const numChars = 26 9 | 10 | type TrieNode struct { 11 | isLastChar bool 12 | child [numChars]*TrieNode 13 | } 14 | 15 | type Trie struct { 16 | root *TrieNode 17 | } 18 | 19 | func (t *Trie) Insert(s string) { 20 | if s == "" { 21 | return 22 | } 23 | 24 | str := strings.ToLower(s) 25 | t.root = t.insertUtil(t.root, str, 0) 26 | } 27 | 28 | func (t *Trie) insertUtil(curr *TrieNode, str string, index int) *TrieNode { 29 | if curr == nil { 30 | curr = &TrieNode{} 31 | } 32 | if index == len(str) { 33 | curr.isLastChar = true 34 | } else { 35 | charIndex := str[index] - 'a' 36 | curr.child[charIndex] = t.insertUtil(curr.child[charIndex], str, index+1) 37 | } 38 | return curr 39 | } 40 | 41 | func (t *Trie) Remove(s string) { 42 | if s == "" { 43 | return 44 | } 45 | 46 | str := strings.ToLower(s) 47 | t.removeUtil(t.root, str, 0) 48 | } 49 | 50 | func (t *Trie) removeUtil(curr *TrieNode, str string, index int) { 51 | if curr == nil { 52 | return 53 | } 54 | 55 | if index == len(str) { 56 | curr.isLastChar = false 57 | return 58 | } 59 | charIndex := str[index] - 'a' 60 | t.removeUtil(curr.child[charIndex], str, index+1) 61 | } 62 | 63 | func (t *Trie) Find(s string) bool { 64 | if s == "" { 65 | return false 66 | } 67 | str := strings.ToLower(s) 68 | return t.findUtil(t.root, str, 0) 69 | } 70 | 71 | func (t *Trie) findUtil(curr *TrieNode, str string, index int) bool { 72 | if curr == nil { 73 | return false 74 | } 75 | if index == len(str) { 76 | return curr.isLastChar 77 | } 78 | charIndex := str[index] - 'a' 79 | return t.findUtil(curr.child[charIndex], str, index+1) 80 | } 81 | 82 | // Testing code. 83 | func main() { 84 | t := &Trie{} 85 | t.Insert("banana") 86 | t.Insert("apple") 87 | t.Insert("mango") 88 | fmt.Println("Apple Found:", t.Find("apple")) 89 | fmt.Println("Grapes Found:", t.Find("grapes")) 90 | fmt.Println("Banana Found:", t.Find("banana")) 91 | } 92 | -------------------------------------------------------------------------------- /Tree/BinaryIndexTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type BinaryIndexTree struct { 6 | BIT []int 7 | size int 8 | } 9 | 10 | func NewBinaryIndexTree(arr []int) *BinaryIndexTree { 11 | t := &BinaryIndexTree{ 12 | size: len(arr), 13 | BIT: make([]int, len(arr)+1), 14 | } 15 | 16 | // Populating bit. 17 | for i := 0; i < t.size; i++ { 18 | t.Update(i, arr[i]) 19 | } 20 | return t 21 | } 22 | 23 | func (t *BinaryIndexTree) Update(index int, val int) { 24 | // Index in bit is 1 more than the input array. 25 | index++ 26 | 27 | // Traverse to ancestors of nodes. 28 | for index <= t.size { 29 | // Add val to the current node of the Binary Index Tree. 30 | t.BIT[index] += val 31 | // Next element that needs to store val. 32 | index += index & -index 33 | } 34 | } 35 | 36 | func (t *BinaryIndexTree) Set(arr []int, index int, val int) { 37 | diff := val - arr[index] 38 | arr[index] = val 39 | 40 | // Difference is propagated. 41 | t.Update(index, diff) 42 | } 43 | 44 | // Range sum in the range start to end. 45 | func (t *BinaryIndexTree) RangeSum(start int, end int) int { 46 | // Check for error conditions. 47 | if start > end || start < 0 || end > t.size-1 { 48 | fmt.Println("Invalid input.") 49 | return -1 50 | } 51 | return t.PrefixSum(end) - t.PrefixSum(start-1) 52 | } 53 | 54 | // Prefix sum in the range 0 to index. 55 | func (t *BinaryIndexTree) PrefixSum(index int) int { 56 | sum := 0 57 | index++ 58 | 59 | // Traverse ancestors of Binary Index Tree nodes. 60 | for index > 0 { 61 | // Add the current element to the sum. 62 | sum += t.BIT[index] 63 | // Calculate the parent index. 64 | index -= index & -index 65 | } 66 | return sum 67 | } 68 | 69 | func main() { 70 | arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} 71 | tree := NewBinaryIndexTree(arr) 72 | fmt.Println("Sum of elements in range(0, 5): ", tree.PrefixSum(5)) 73 | fmt.Println("Sum of elements in range(2, 5): ", tree.RangeSum(2, 5)) 74 | tree.Set(arr, 3, 10) 75 | fmt.Println("Sum of elements in range(0, 5): ", tree.PrefixSum(5)) 76 | } 77 | -------------------------------------------------------------------------------- /Tree/SegmentTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type SegmentTree struct { 9 | segArr []int 10 | size int 11 | } 12 | 13 | func NewSegmentTree(input []int) (self *SegmentTree) { 14 | self = &SegmentTree{} 15 | self.size = len(input) 16 | // Height of segment tree. 17 | x := (math.Ceil(math.Log(float64(self.size)) / math.Log(2))) 18 | //Maximum size of segment tree 19 | maxSize := int(2*math.Pow(2.0, x) - 1) 20 | // Allocate memory for segment tree 21 | self.segArr = make([]int, maxSize) 22 | self.constructST(input, 0, self.size-1, 0) 23 | return 24 | } 25 | 26 | func (self *SegmentTree) constructST(input []int, start int, end int, index int) int { 27 | // Store it in current node of the segment tree and return 28 | if start == end { 29 | self.segArr[index] = input[start] 30 | return input[start] 31 | } 32 | // If there are more than one elements, 33 | // then traverse left and right subtrees 34 | // and store the sum of values in current node. 35 | mid := (start + end) / 2 36 | self.segArr[index] = self.constructST(input, start, mid, index*2+1) + self.constructST(input, mid+1, end, index*2+2) 37 | return self.segArr[index] 38 | } 39 | 40 | func (self *SegmentTree) GetSum(start int, end int) int { 41 | // Check for error conditions. 42 | if start > end || start < 0 || end > self.size-1 { 43 | fmt.Println("Invalid Input.") 44 | return -1 45 | } 46 | return self.getSumUtil(0, self.size-1, start, end, 0) 47 | } 48 | 49 | func (self *SegmentTree) getSumUtil(segStart int, segEnd int, queryStart int, queryEnd int, index int) int { 50 | if queryStart <= segStart && segEnd <= queryEnd { 51 | return self.segArr[index] 52 | } 53 | if segEnd < queryStart || queryEnd < segStart { 54 | return 0 55 | } 56 | // Segment tree is partly overlaps with the query range. 57 | mid := (segStart + segEnd) / 2 58 | return self.getSumUtil(segStart, mid, queryStart, queryEnd, 2*index+1) + self.getSumUtil(mid+1, segEnd, queryStart, queryEnd, 2*index+2) 59 | } 60 | 61 | func (self *SegmentTree) Set(arr []int, ind int, val int) { 62 | // Check for error conditions. 63 | if ind < 0 || ind > self.size-1 { 64 | fmt.Println("Invalid Input.") 65 | return 66 | } 67 | arr[ind] = val 68 | // Set new value in segment tree 69 | self.setUtil(0, self.size-1, ind, val, 0) 70 | } 71 | 72 | // Always diff will be returned. 73 | func (self *SegmentTree) setUtil(segStart int, segEnd int, ind int, val int, index int) int { 74 | // set index lies outside the range of current segment. 75 | // So diff to its parent node will be zero. 76 | if ind < segStart || ind > segEnd { 77 | return 0 78 | } 79 | // If the input index is in range of this node, then set the 80 | // value of the node and its children 81 | if segStart == segEnd { 82 | if segStart == ind { // Index that needs to be set. 83 | diff := val - self.segArr[index] 84 | self.segArr[index] = val 85 | return diff 86 | } else { 87 | return 0 88 | } 89 | } 90 | mid := (segStart + segEnd) / 2 91 | diff := self.setUtil(segStart, mid, ind, val, 2*index+1) + 92 | self.setUtil(mid+1, segEnd, ind, val, 2*index+2) 93 | // Current node value is set with diff. 94 | self.segArr[index] = self.segArr[index] + diff 95 | // Value of diff is propagated to the parent node. 96 | return diff 97 | } 98 | 99 | func main() { 100 | arr := []int{1, 2, 4, 8, 16, 32, 64} 101 | tree := NewSegmentTree(arr) 102 | fmt.Println("Sum of values in the range(0, 3): ", tree.GetSum(1, 3)) 103 | fmt.Println("Sum of values of all the elements: ", tree.GetSum(0, len(arr)-1)) 104 | tree.Set(arr, 1, 10) 105 | fmt.Println("Sum of values in the range(0, 3): ", tree.GetSum(1, 3)) 106 | fmt.Println("Sum of values of all the elements: ", tree.GetSum(0, len(arr)-1)) 107 | } 108 | 109 | /* 110 | Sum of values in the range(0, 3): 14 111 | Sum of values of all the elements: 127 112 | Sum of values in the range(0, 3): 22 113 | Sum of values of all the elements: 135 114 | */ 115 | -------------------------------------------------------------------------------- /Tree/rangeMaxST.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type rangeMaxST struct { 9 | segArr []int 10 | n int 11 | } 12 | 13 | func NewrangeMaxST(input []int) *rangeMaxST { 14 | self := &rangeMaxST{} 15 | self.n = len(input) 16 | // Height of segment tree. 17 | x := math.Ceil(math.Log(float64(self.n)) / math.Log(2)) 18 | // Maximum size of segment tree 19 | maxSize := int(2*math.Pow(2.0, x) - 1) 20 | // Allocate memory for segment tree 21 | self.segArr = make([]int, maxSize) 22 | self.constructST(input, 0, self.n-1, 0) 23 | return self 24 | } 25 | 26 | func (self *rangeMaxST) constructST(input []int, start int, end int, index int) int { 27 | // Store it in the current node of the segment tree and return 28 | if start == end { 29 | self.segArr[index] = input[start] 30 | return input[start] 31 | } 32 | // If there are more than one elements, 33 | // then traverse left and right subtrees 34 | // and store the minimum of values in the current node. 35 | mid := (start + end) / 2 36 | self.segArr[index] = self.max(self.constructST(input, start, mid, index*2+1), self.constructST(input, mid+1, end, index*2+2)) 37 | return self.segArr[index] 38 | } 39 | 40 | func (self *rangeMaxST) max(first int, second int) int { 41 | if first > second { 42 | return first 43 | } 44 | return second 45 | } 46 | 47 | func (self *rangeMaxST) GetMax(start int, end int) int { 48 | // Check for error conditions. 49 | if start > end || start < 0 || end > self.n-1 { 50 | fmt.Println("Invalid Input.") 51 | return math.MinInt32 52 | } 53 | return self.getMaxUtil(0, self.n-1, start, end, 0) 54 | } 55 | 56 | func (self *rangeMaxST) getMaxUtil(segStart int, segEnd int, queryStart int, queryEnd int, index int) int { 57 | if queryStart <= segStart && segEnd <= queryEnd { 58 | return self.segArr[index] 59 | } 60 | if segEnd < queryStart || queryEnd < segStart { 61 | return math.MinInt32 62 | } 63 | // Segment tree partly overlaps with the query range. 64 | mid := (segStart + segEnd) / 2 65 | return self.max(self.getMaxUtil(segStart, mid, queryStart, queryEnd, 2*index+1), self.getMaxUtil(mid+1, segEnd, queryStart, queryEnd, 2*index+2)) 66 | } 67 | 68 | func (self *rangeMaxST) Update(ind int, val int) { 69 | // Check for error conditions. 70 | if ind < 0 || ind > self.n-1 { 71 | fmt.Println("Invalid Input.") 72 | return 73 | } 74 | // Update the values in the segment tree 75 | self.updateUtil(0, self.n-1, ind, val, 0) 76 | } 77 | 78 | // Always min inside valid range will be returned. 79 | func (self *rangeMaxST) updateUtil(segStart int, segEnd int, ind int, val int, index int) int { 80 | // Update index lies outside the range of the current segment. 81 | // So the minimum will not change. 82 | if ind < segStart || ind > segEnd { 83 | return self.segArr[index] 84 | } 85 | // If the input index is in the range of this node, then update the 86 | // value of the node and its children. 87 | if segStart == segEnd { 88 | if segStart == ind { // Index value needs to be updated. 89 | self.segArr[index] = val 90 | return val 91 | } else { 92 | return self.segArr[index] // Index value is not changed. 93 | } 94 | } 95 | mid := (segStart + segEnd) / 2 96 | // Current node value is updated with min. 97 | self.segArr[index] = self.max(self.updateUtil(segStart, mid, ind, val, 2*index+1), 98 | self.updateUtil(mid+1, segEnd, ind, val, 2*index+2)) 99 | // The value of diff is propagated to the parent node. 100 | return self.segArr[index] 101 | } 102 | 103 | func main() { 104 | arr := []int{1, 8, 2, 7, 3, 6, 4, 5} 105 | tree := NewrangeMaxST(arr) 106 | fmt.Println("Max value in the range(1, 5): ", tree.GetMax(1, 5)) 107 | fmt.Println("Max value in the range(2, 7): ", tree.GetMax(2, 7)) 108 | fmt.Println("Max value of all the elements: ", tree.GetMax(0, len(arr)-1)) 109 | tree.Update(2, 9) 110 | fmt.Println("Max value in the range(1, 5): ", tree.GetMax(1, 5)) 111 | fmt.Println("Max value of all the elements: ", tree.GetMax(0, len(arr)-1)) 112 | } 113 | 114 | /* 115 | Max value in the range(1, 5): 8 116 | Max value in the range(2, 7): 7 117 | Max value of all the elements: 8 118 | Max value in the range(1, 5): 9 119 | Max value of all the elements: 9 120 | */ 121 | -------------------------------------------------------------------------------- /Tree/rmqST.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type rmqST struct { 9 | segArr []int 10 | n int 11 | } 12 | 13 | func NewRmqST(input []int) (self *rmqST) { 14 | self = &rmqST{} 15 | // Height of segment tree. 16 | self.n = len(input) 17 | // Maximum size of segment tree 18 | x := (math.Ceil(math.Log(float64(self.n)) / math.Log(2))) 19 | // Allocate memory for segment tree 20 | maxSize := int(2*math.Pow(2.0, x) - 1) 21 | self.segArr = make([]int, maxSize) 22 | self.constructST(input, 0, self.n-1, 0) 23 | return 24 | } 25 | 26 | func (self *rmqST) constructST(input []int, start int, end int, index int) int { 27 | // Store it in the current node of the segment tree and return 28 | if start == end { 29 | self.segArr[index] = input[start] 30 | return input[start] 31 | } 32 | // If there are more than one element, 33 | // then traverse left and right subtrees 34 | // and store the minimum of values in the current node. 35 | mid := (start + end) / 2 36 | self.segArr[index] = self.min(self.constructST(input, start, mid, index*2+1), self.constructST(input, mid+1, end, index*2+2)) 37 | return self.segArr[index] 38 | } 39 | 40 | func (self *rmqST) Update(ind int, val int) { 41 | // Check for error conditions. 42 | if ind < 0 || ind > self.n-1 { 43 | fmt.Println("Invalid Input.") 44 | return 45 | } 46 | // Update the values in the segment tree 47 | self.updateUtil(0, self.n-1, ind, val, 0) 48 | } 49 | 50 | // Always min inside the valid range will be returned. 51 | func (self *rmqST) updateUtil(segStart int, segEnd int, ind int, val int, index int) int { 52 | // Update index lies outside the range of the current segment. 53 | // So the minimum will not change. 54 | if ind < segStart || ind > segEnd { 55 | return self.segArr[index] 56 | } 57 | // If the input index is in the range of this node, then update the 58 | // value of the node and its children 59 | if segStart == segEnd { 60 | if segStart == ind { // Index value needs to be updated. 61 | self.segArr[index] = val 62 | return val 63 | } else { 64 | return self.segArr[index] // index value is not changed. 65 | } 66 | } 67 | mid := (segStart + segEnd) / 2 68 | // Current node value is updated with min. 69 | self.segArr[index] = self.min(self.updateUtil(segStart, mid, ind, val, 2*index+1), self.updateUtil(mid+1, segEnd, ind, val, 2*index+2)) 70 | // Value of diff is propagated to the parent node. 71 | return self.segArr[index] 72 | } 73 | 74 | func (self *rmqST) GetMin(start int, end int) int { 75 | // Check for error conditions. 76 | if start > end || start < 0 || end > self.n-1 { 77 | fmt.Println("Invalid Input.") 78 | return math.MaxInt32 79 | } 80 | return self.getMinUtil(0, self.n-1, start, end, 0) 81 | } 82 | 83 | func (self *rmqST) getMinUtil(segStart int, segEnd int, queryStart int, queryEnd int, index int) int { 84 | if queryStart <= segStart && segEnd <= queryEnd { 85 | return self.segArr[index] 86 | } 87 | if segEnd < queryStart || queryEnd < segStart { 88 | return math.MaxInt32 89 | } 90 | // Segment tree partly overlaps with the query range. 91 | mid := (segStart + segEnd) / 2 92 | return self.min(self.getMinUtil(segStart, mid, queryStart, queryEnd, 2*index+1), self.getMinUtil(mid+1, segEnd, queryStart, queryEnd, 2*index+2)) 93 | } 94 | 95 | func (self *rmqST) min(first int, second int) int { 96 | if first < second { 97 | return first 98 | } 99 | return second 100 | } 101 | 102 | func main() { 103 | arr := []int{2, 3, 1, 7, 12, 5} 104 | tree := NewRmqST(arr) 105 | fmt.Println("Min value in the range(1, 5):", tree.GetMin(1, 5)) 106 | fmt.Println("Min value of all the elements:", tree.GetMin(0, len(arr)-1)) 107 | tree.Update(2, -1) 108 | fmt.Println("Min value in the range(1, 5):", tree.GetMin(1, 5)) 109 | fmt.Println("Min value of all the elements:", tree.GetMin(0, len(arr)-1)) 110 | tree.Update(5, -2) 111 | fmt.Println("Min value in the range(0, 4):", tree.GetMin(0, 4)) 112 | fmt.Println("Min value of all the elements:", tree.GetMin(0, len(arr)-1)) 113 | } 114 | 115 | /* 116 | Min value in the range(1, 5): 1 117 | Min value of all the elements: 1 118 | Min value in the range(1, 5): -1 119 | Min value of all the elements: -1 120 | Min value in the range(0, 4): -1 121 | Min value of all the elements: -2 122 | */ 123 | -------------------------------------------------------------------------------- /script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #script to recursively travel a dir of n levels 4 | 5 | function traverse() { 6 | for file in "$1"/* 7 | do 8 | if [ ! -d "${file}" ] ; then 9 | if [[ ${file} == *.go ]] ; then 10 | echo "${file} is go file" 11 | go build "${file}" &> "$1".log 12 | sleep 60 & 13 | # else 14 | # # echo "${file} is a file" 15 | fi 16 | else 17 | echo "entering recursion with: ${file}" 18 | traverse "${file}" 19 | fi 20 | done 21 | } 22 | 23 | function main() { 24 | traverse "$1" 25 | } 26 | 27 | main "$1" 28 | --------------------------------------------------------------------------------