├── .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 |
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.core stateVersionNumber 30
--------------------------------------------------------------------------------
/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree:
--------------------------------------------------------------------------------
1 | org.eclipse.dltk.core org.eclipse.cdt.core org.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 |
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 |
11 |
--------------------------------------------------------------------------------
/.metadata/.plugins/org.eclipse.equinox.p2.ui/dialog_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
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_HOME JRE_SRC JUNIT_SRC_HOME M2_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 |
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 |
6 |
--------------------------------------------------------------------------------
/.metadata/.plugins/org.eclipse.ui.intro/introstate:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | 
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 |
--------------------------------------------------------------------------------