├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── algorithms
├── 01knapsack_dp
│ └── 01knapsack_dp.go
├── a_star
│ ├── 8_puzzle
│ │ ├── 8_puzzle.go
│ │ ├── README.md
│ │ ├── a_star.go
│ │ └── priority_queue.go
│ ├── directed_graph
│ │ ├── a_star.go
│ │ ├── graph.go
│ │ └── priority_queue.go
│ └── undirected_graph
│ │ ├── a_star.go
│ │ ├── graph.go
│ │ └── priority_queue.go
├── activity_selection_gp
│ ├── activity_selection_gp.go
│ └── quick_sort.go
├── assembly_line_scheduling
│ └── assembly_scheduling.go
├── binary_reflected_gray_codes
│ └── brgc.go
├── closest_pair_problem
│ ├── cpp_brute_force
│ │ ├── cpp_brute_force.go
│ │ └── sample.txt
│ └── cpp_divide_conquer
│ │ ├── cpp_divide_conquer.go
│ │ ├── sample.txt
│ │ └── sort.go
├── combinations
│ ├── with_r
│ │ └── combinations.go
│ └── without_r
│ │ └── combinations.go
├── convex_hull
│ ├── ch_brute_force
│ │ ├── ch_brute_force.go
│ │ ├── helpers.go
│ │ └── sample.txt
│ └── ch_divide_conquer
│ │ ├── ch_divide_conquer.go
│ │ ├── helpers.go
│ │ ├── sample.txt
│ │ └── sort.go
├── expression_conversions
│ ├── infix_postfix
│ │ └── infix_postfix.go
│ ├── infix_prefix
│ │ └── infix_prefix.go
│ ├── postfix_infix
│ │ └── postfix_infix.go
│ ├── postfix_prefix
│ │ └── postfix_prefix.go
│ ├── prefix_infix
│ │ └── prefix_infix.go
│ └── prefix_postfix
│ │ └── prefix_postfix.go
├── gcd
│ ├── README.md
│ └── gcd.go
├── graphs
│ ├── articulation_point_detection
│ │ ├── articulation_point.go
│ │ ├── graph.go
│ │ └── traversal.go
│ ├── bellman_ford
│ │ ├── bellman_ford.go
│ │ └── graph.go
│ ├── bridge_detection
│ │ ├── bridge_detection.go
│ │ ├── graph.go
│ │ └── traversal.go
│ ├── dijkstra
│ │ ├── dijkstra.go
│ │ ├── graph.go
│ │ └── priority_queue.go
│ ├── floyd_warshall
│ │ ├── floyd_warshall.go
│ │ └── graph.go
│ ├── kruskals
│ │ ├── graph.go
│ │ ├── heap.go
│ │ └── kruskals.go
│ ├── prims
│ │ ├── graph.go
│ │ ├── heap.go
│ │ └── prims.go
│ ├── topological_sort
│ │ ├── graph.go
│ │ └── topological_sort.go
│ ├── traversals
│ │ ├── cd_directed_graph_traversals
│ │ │ ├── cycle_detection.go
│ │ │ ├── graph.go
│ │ │ └── traversal.go
│ │ └── cd_undirected_graph_traversals
│ │ │ ├── cycle_detection.go
│ │ │ ├── graph.go
│ │ │ └── traversals.go
│ ├── tsp
│ │ ├── tsp_dynamic
│ │ │ ├── directed_graph
│ │ │ │ ├── graph.go
│ │ │ │ ├── helpers.go
│ │ │ │ └── tsp_dynamic.go
│ │ │ └── undirected_graph
│ │ │ │ ├── graph.go
│ │ │ │ ├── helpers.go
│ │ │ │ └── tsp_dynamic.go
│ │ └── tsp_naive
│ │ │ ├── directed_graph
│ │ │ ├── graph.go
│ │ │ ├── lo_permutations.go
│ │ │ └── tsp_naive.go
│ │ │ └── undirected_graph
│ │ │ ├── graph.go
│ │ │ ├── lo_permutations.go
│ │ │ └── tsp_naive.go
│ └── union_find
│ │ ├── graph.go
│ │ └── union_find.go
├── huffman_codes
│ ├── heap.go
│ └── huffman_codes.go
├── job_scheduling_gp
│ ├── job_scheduling_gp.go
│ └── quick_sort.go
├── lcm
│ └── lcm.go
├── lcs
│ └── iterative_dp
│ │ └── lcs_iterative_dp.go
├── lo_permutations
│ └── lo_permutations.go
├── longest_palindrome_substring
│ ├── brute_force
│ │ └── brute_force.go
│ └── manchers
│ │ └── manchers.go
├── making_change_dp
│ └── making_change_dp.go
├── order_statistics
│ ├── naive_approach
│ │ ├── heap.go
│ │ └── naive_approach.go
│ ├── quick_select
│ │ └── quick_select.go
│ └── worst_case_linear_time
│ │ └── wclt.go
├── power_set
│ └── power_set.go
├── searching
│ ├── binary_search
│ │ └── binary_search.go
│ ├── interpolation_search
│ │ └── interpolation_search.go
│ ├── linear_search
│ │ └── linear_search.go
│ └── ternary_search
│ │ └── ternary_search.go
├── sieve_of_eratosthenes
│ └── sieve_of_eratosthenes.go
├── sorting
│ ├── binary_insertion_sort
│ │ └── binary_insertion_sort.go
│ ├── bubble_sort
│ │ └── bubble_sort.go
│ ├── bucket_sort
│ │ └── bucket_sort.go
│ ├── counting_sort
│ │ └── counting_sort.go
│ ├── heap_sort
│ │ └── heap_sort.go
│ ├── insertion_sort
│ │ └── insertion_sort.go
│ ├── merge_sort
│ │ └── merge_sort.go
│ ├── quick_sort
│ │ └── quick_sort.go
│ ├── radix_sort
│ │ └── radix_sort.go
│ ├── selection_sort
│ │ └── selection_sort.go
│ └── shell_sort
│ │ └── shell_sort.go
├── string_matching
│ ├── boyer_moore
│ │ └── boyer_moore.go
│ ├── horspool
│ │ └── horspool.go
│ ├── knuth_morris_pratt
│ │ └── knuth_morris_pratt.go
│ ├── naive_pattern_matching
│ │ └── naive_pattern_matching.go
│ └── rabin_karp
│ │ └── rabin_karp.go
└── toh
│ └── toh.go
├── graphs
├── directed_unweighted
│ ├── graph.go
│ └── traversal.go
├── directed_weighted
│ ├── graph.go
│ └── traversal.go
├── undirected_unweighted
│ ├── graph.go
│ └── traversal.go
└── undirected_weighted
│ ├── graph.go
│ └── traversal.go
├── heaps
├── max_binary_heap
│ └── max_binary_heap.go
└── min_binary_heap
│ └── min_binary_heap.go
├── linked_lists
├── circular_doubly_ll
│ └── circular_doubly_ll.go
├── circular_ll
│ └── circular_ll.go
├── doubly_ll
│ └── doubly_ll.go
├── pres_rev_single_ll
│ ├── RGIF2.gif
│ └── pres_single_ll.go
└── single_ll
│ └── single_ll.go
├── notes
├── graphs
│ └── README.md
├── heaps
│ └── README.md
├── linked_lists
│ └── README.md
├── queues
│ └── README.md
├── stack
│ └── README.md
└── trees
│ └── README.md
├── queues
├── cdqueue
│ └── cdqueue.go
├── cqueue
│ └── cqueue.go
├── dqueue
│ └── dqueue.go
├── priority_queue
│ └── priority_queue.go
└── simple_queue
│ └── simple_queue.go
├── resources.md
├── stack
└── stack.go
└── trees
├── avl_tree_using_ll
├── avl_tree_using_ll.go
└── traversal.go
├── bst_using_arr
├── bst_using_arr.go
└── traversal.go
├── bst_using_ll
├── bst_using_ll.go
└── traversal.go
├── simple_bt_using_arr
├── simple_bt_using_arr.go
└── traversal.go
└── simple_bt_using_ll
├── simple_bt_using_ll.go
└── traversal.go
/.gitignore:
--------------------------------------------------------------------------------
1 | *.exe
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at deveshpatel7643@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Devesh Patel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/algorithms/01knapsack_dp/01knapsack_dp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func knapsack() {
9 | op := make([][]int, size+1)
10 | for i := range op {
11 | op[i] = make([]int, capacity+1)
12 | for j := range op[i] {
13 | op[i][0] = 0
14 | op[0][j] = 0
15 | }
16 | }
17 |
18 | for i := range op {
19 | for j := range op[i] {
20 | if i == 0 || j == 0 {
21 | continue
22 | } else if j < weights[i] {
23 | op[i][j] = op[i-1][j]
24 | } else if j >= weights[i] {
25 | op[i][j] = int(math.Max(float64(op[i-1][j]), float64(op[i-1][j-weights[i]]+values[i])))
26 | }
27 | }
28 | }
29 |
30 | // finding the right weights and values from the matrix generated
31 | i := size
32 | j := capacity
33 | var finalWeights []int
34 | var finalValues []int
35 |
36 | for i != 0 {
37 | if op[i][j] == op[i-1][j] {
38 | i--
39 | } else {
40 | finalWeights = append(finalWeights, weights[i])
41 | finalValues = append(finalValues, values[i])
42 | j -= weights[i]
43 | }
44 | }
45 |
46 | // printing the answer
47 | fmt.Println("Matrix formed:")
48 | for i := range op {
49 | fmt.Println(op[i])
50 | }
51 | fmt.Println("\nWeights taken:")
52 | fmt.Println(finalWeights)
53 | fmt.Println("Values taken:")
54 | fmt.Println(finalValues)
55 | }
56 |
57 | var weights, values []int
58 | var capacity, size int
59 |
60 | func init() {
61 | weights = append(weights, 0)
62 | values = append(values, 0)
63 | }
64 |
65 | func main() {
66 | var temp int
67 | fmt.Println("\n-- 0-1 Knapsack Problem using Dynamic Programming --")
68 | fmt.Print("\nEnter the number of objects: ")
69 | fmt.Scanf("%d\n", &size)
70 | fmt.Println("Start entering weight and value of each object:")
71 | for i := 0; i < size; i++ {
72 | fmt.Print("\nWeight: ")
73 | fmt.Scanf("%d\n", &temp)
74 | weights = append(weights, temp)
75 | fmt.Print("Value: ")
76 | fmt.Scanf("%d\n", &temp)
77 | values = append(values, temp)
78 | }
79 | fmt.Print("\nEnter the capacity of knapsack: ")
80 | fmt.Scanf("%d\n", &capacity)
81 | knapsack()
82 | }
83 |
84 | // FORMULA
85 | // stp1: make v[i][0] and v[0][j] = 0
86 | // stp2: if j < weights[i] then v[i][j] = v[i-1][j]
87 | // stp3: if j >= weights[i] then v[i][j] = max(v[i-1][j], v[i-1][j-weights[i]]+v[i])
88 |
--------------------------------------------------------------------------------
/algorithms/a_star/8_puzzle/8_puzzle.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type matrix [][]int
6 | type sliceOfMatrix []matrix
7 |
8 | // input scrambled puzzle
9 | var inputPuzzle matrix
10 |
11 | // the final required output puzzle
12 | var outputPuzzle matrix
13 |
14 | // the steps taken to reach from scrambled puzzle to required output puzzle
15 | var solvedSteps sliceOfMatrix
16 |
17 | // heap stores the list of nodes and returns the one having the least cost
18 | var heap []*Node
19 |
20 | // Node represents value, path, level and move
21 | // value is the cost of the last matrix in path
22 | // path is the list of matrices which represents the traversal (steps) done from the initial matrix
23 | // level represents the depth at which the current (last matrix from path) state is
24 | // parentBlankCell represents the row and column in which the blank cell was in the parent state
25 | type Node struct {
26 | value int
27 | path sliceOfMatrix
28 | level int
29 | parentBlankCell []int
30 | }
31 |
32 | func init() {
33 | outputPuzzle = make(matrix, 3)
34 | solvedSteps = make(sliceOfMatrix, 0)
35 | heap = make([]*Node, 0)
36 | inputPuzzle = make(matrix, 3)
37 |
38 | // initialize outputPuzzle
39 | for i := range outputPuzzle {
40 | outputPuzzle[i] = make([]int, 3)
41 | for j := range outputPuzzle[i] {
42 | outputPuzzle[i][j] = 0
43 | }
44 | }
45 |
46 | // initialize inputPuzzle
47 | for i := range inputPuzzle {
48 | inputPuzzle[i] = make([]int, 3)
49 | for j := range inputPuzzle[i] {
50 | inputPuzzle[i][j] = 0
51 | }
52 | }
53 | }
54 |
55 | func main() {
56 | // scan the input values
57 | fmt.Println("\n-- 8 Puzzle problem using A* Algorithm --")
58 | fmt.Println("\n-- Note: For blank cell use '0' --")
59 |
60 | fmt.Println("\nStart entering desired 3x3 output puzzle:")
61 | for i := range outputPuzzle {
62 | for j := range outputPuzzle[i] {
63 | value := -1
64 | fmt.Print("Enter for ", i+1, j+1, ": ")
65 | fmt.Scanf("%d\n", &value)
66 | outputPuzzle[i][j] = value
67 | }
68 | fmt.Println("")
69 | }
70 |
71 | if !outputPuzzle.isValid() {
72 | fmt.Println("\n-- Invalid output puzzle. --")
73 | return
74 | }
75 |
76 | fmt.Println("\nStart entering 3x3 scrambled input puzzle:")
77 | for i := range inputPuzzle {
78 | for j := range inputPuzzle[i] {
79 | value := -1
80 | fmt.Print("Enter for ", i+1, j+1, ": ")
81 | fmt.Scanf("%d\n", &value)
82 | inputPuzzle[i][j] = value
83 | }
84 | fmt.Println("")
85 | }
86 |
87 | // print the desired output puzzle
88 | fmt.Println("\nYour desired output puzzle is:")
89 | outputPuzzle.displayMatrix()
90 |
91 | // print the input scrambled puzzle
92 | fmt.Println("\nYour scrambled puzzle is: ")
93 | inputPuzzle.displayMatrix()
94 |
95 | // validate the puzzle
96 | if inputPuzzle.isValid() {
97 | fmt.Println("\nA* Algorithm started...")
98 | inputPuzzle.aStar()
99 | } else {
100 | fmt.Println("-- Your input puzzle is invalid. --")
101 | }
102 | }
103 |
104 | // puzzle = input - output
105 | // puzzle = [][]int{[]int{2, 8, 3}, []int{1, 6, 4}, []int{7, 0, 5}} - [][]int{[]int{1, 2, 3}, []int{8, 0, 4}, []int{7, 6, 5}}
106 | // puzzle = matrix{[]int{1, 8, 2}, []int{0, 4, 3}, []int{7, 6, 5}} - [][]int{[]int{1, 2, 3}, []int{4, 5, 6}, []int{7, 8, 0}}
107 |
--------------------------------------------------------------------------------
/algorithms/a_star/8_puzzle/README.md:
--------------------------------------------------------------------------------
1 | #### Memory and Time requirements
2 |
3 | The memory and time requirements to solve the input puzzle depends on the input. For example, consider the below input puzzle:
4 |
5 | **Input**
6 |
7 | ```
8 | 1 2 3
9 | 0 4 6
10 | 7 5 8
11 | ```
12 |
13 | **Required Output**
14 |
15 | ```
16 | 1 2 3
17 | 8 0 4
18 | 7 6 5
19 | ```
20 |
21 | To transform the above input to required output takes subtantially long time and more memory, and may hang your computer, which happened to me 😜, if the algorithm continues to find the solution further.
22 |
23 | #### Few methods to solve 8 Puzzle problem:
24 |
25 | 1. A\* Algorithm
26 | 2. BFS (Breadth First Search)
27 | 3. DFS (Depth First Search)
28 | 4. Best First Search
29 | 5. Iterative Deepening Search
30 |
31 | #### Calculating Cost
32 |
33 | The `calculateCost` function implemented in this implementation can be changed to calculate cost using different methods. Following are some ways to calculate the cost of any puzzle:
34 |
35 | 1. Number of mismatched tiles (Implemented)
36 | 2. Manhattan distance
37 | 3. Euclidean distance
38 |
39 | #### References
40 |
41 | Live Demo: [http://tristanpenman.com/demos/n-puzzle/](http://tristanpenman.com/demos/n-puzzle/)
42 |
43 | List of sample inputs: [https://www.andrew.cmu.edu/course/15-121/labs/HW-7%20Slide%20Puzzle/lab.html](https://www.andrew.cmu.edu/course/15-121/labs/HW-7%20Slide%20Puzzle/lab.html)
44 |
--------------------------------------------------------------------------------
/algorithms/a_star/8_puzzle/priority_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Note - Lower priority value processes will be run first. Hence this is implemented using min heap.
4 |
5 | import (
6 | "fmt"
7 | "math"
8 | )
9 |
10 | // Enqueue inserts a node in a heap
11 | func Enqueue(node *Node) {
12 | heap = append(heap, node)
13 | minHeapify()
14 | }
15 |
16 | func minHeapify() {
17 | idx := len(heap) - 1
18 | element := heap[idx]
19 | for idx > 0 {
20 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
21 | parent := heap[parentIdx]
22 | if element.value >= parent.value {
23 | break
24 | }
25 | heap[parentIdx] = element
26 | heap[idx] = parent
27 | idx = parentIdx
28 | }
29 | }
30 |
31 | // Dequeue will remove a node from heap
32 | func Dequeue() *Node {
33 | if len(heap) == 0 || heap[0] == nil {
34 | fmt.Println("\n-- Heap is empty. --")
35 | return nil
36 | }
37 | min := heap[0]
38 | end := heap[len(heap)-1]
39 | heap = heap[0 : len(heap)-1]
40 | if len(heap) > 0 {
41 | heap[0] = end
42 | bubbleDown()
43 | }
44 | return min
45 | }
46 |
47 | func bubbleDown() {
48 | idx := 0
49 | length := len(heap)
50 | element := heap[0]
51 | for {
52 | leftChildIdx := (2 * idx) + 1
53 | rightChildIdx := (2 * idx) + 2
54 | var leftChild, rightChild *Node
55 | var swap int
56 |
57 | if leftChildIdx < length {
58 | leftChild = heap[leftChildIdx]
59 | if leftChild.value < element.value {
60 | swap = leftChildIdx
61 | }
62 | }
63 | if rightChildIdx < length {
64 | rightChild = heap[rightChildIdx]
65 | if (rightChild.value < element.value && swap == 0) || (rightChild.value < leftChild.value && swap != 0) {
66 | swap = rightChildIdx
67 | }
68 | }
69 |
70 | if swap == 0 {
71 | break
72 | }
73 | heap[idx] = heap[swap]
74 | heap[swap] = element
75 | idx = swap
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/algorithms/a_star/directed_graph/a_star.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | func (g graph) runAStarAlgo(initialVtx, goalVtx string) {
9 | for vtx := range g[initialVtx] {
10 | f := g[initialVtx][vtx].value + vtxWeights[g[initialVtx][vtx].name]
11 | Enqueue(&Node{name: initialVtx + "-" + g[initialVtx][vtx].name, value: f})
12 | }
13 | path := g.traverseFurther(Dequeue(), goalVtx)
14 | fmt.Println("Best Path is:", path.name)
15 | fmt.Println("The cost is:", path.value)
16 | }
17 |
18 | func (g graph) traverseFurther(bestPath *Node, goalVtx string) *Node {
19 | vertices := strings.Split(bestPath.name, "-")
20 | currVtx := vertices[len(vertices)-1]
21 | for vtx := range g[currVtx] {
22 | visitingVtx := g[currVtx][vtx]
23 | f := bestPath.value - vtxWeights[currVtx] + g[currVtx][vtx].value + vtxWeights[visitingVtx.name]
24 | Enqueue(&Node{name: bestPath.name + "-" + visitingVtx.name, value: f})
25 | }
26 |
27 | nextBestPath := Dequeue()
28 | vertices = strings.Split(nextBestPath.name, "-")
29 | if vertices[len(vertices)-1] != goalVtx {
30 | return g.traverseFurther(nextBestPath, goalVtx)
31 | }
32 |
33 | return nextBestPath
34 | }
35 |
--------------------------------------------------------------------------------
/algorithms/a_star/directed_graph/priority_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Note - Lower priority value processes will be run first. Hence this is implemented using min heap.
4 |
5 | import (
6 | "fmt"
7 | "math"
8 | )
9 |
10 | var heap []*Node
11 |
12 | // Enqueue inserts a node in a heap
13 | func Enqueue(node *Node) {
14 | heap = append(heap, node)
15 | minHeapify()
16 | }
17 |
18 | func minHeapify() {
19 | idx := len(heap) - 1
20 | element := heap[idx]
21 | for idx > 0 {
22 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
23 | parent := heap[parentIdx]
24 | if element.value >= parent.value {
25 | break
26 | }
27 | heap[parentIdx] = element
28 | heap[idx] = parent
29 | idx = parentIdx
30 | }
31 | }
32 |
33 | // Dequeue will remove a node from heap
34 | func Dequeue() *Node {
35 | if len(heap) == 0 || heap[0] == nil {
36 | fmt.Println("\n-- Heap is empty. --")
37 | return nil
38 | }
39 | min := heap[0]
40 | end := heap[len(heap)-1]
41 | heap = heap[0 : len(heap)-1]
42 | if len(heap) > 0 {
43 | heap[0] = end
44 | bubbleDown()
45 | }
46 | return min
47 | }
48 |
49 | func bubbleDown() {
50 | idx := 0
51 | length := len(heap)
52 | element := heap[0]
53 | for {
54 | leftChildIdx := (2 * idx) + 1
55 | rightChildIdx := (2 * idx) + 2
56 | var leftChild, rightChild *Node
57 | var swap int
58 |
59 | if leftChildIdx < length {
60 | leftChild = heap[leftChildIdx]
61 | if leftChild.value < element.value {
62 | swap = leftChildIdx
63 | }
64 | }
65 | if rightChildIdx < length {
66 | rightChild = heap[rightChildIdx]
67 | if (rightChild.value < element.value && swap == 0) || (rightChild.value < leftChild.value && swap != 0) {
68 | swap = rightChildIdx
69 | }
70 | }
71 |
72 | if swap == 0 {
73 | break
74 | }
75 | heap[idx] = heap[swap]
76 | heap[swap] = element
77 | idx = swap
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/algorithms/a_star/undirected_graph/a_star.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | func (g graph) runAStarAlgo(initialVtx, goalVtx string) {
9 | for vtx := range g[initialVtx] {
10 | f := g[initialVtx][vtx].value + vtxWeights[g[initialVtx][vtx].name]
11 | Enqueue(&Node{name: initialVtx + "-" + g[initialVtx][vtx].name, value: f})
12 | }
13 | path := g.traverseFurther(Dequeue(), goalVtx)
14 | fmt.Println("Best Path is:", path.name)
15 | fmt.Println("The cost is:", path.value)
16 | }
17 |
18 | func (g graph) traverseFurther(bestPath *Node, goalVtx string) *Node {
19 | vertices := strings.Split(bestPath.name, "-")
20 | currVtx := vertices[len(vertices)-1]
21 | for vtx := range g[currVtx] {
22 | visitingVtx := g[currVtx][vtx]
23 | f := bestPath.value - vtxWeights[currVtx] + g[currVtx][vtx].value + vtxWeights[visitingVtx.name]
24 | Enqueue(&Node{name: bestPath.name + "-" + visitingVtx.name, value: f})
25 | }
26 |
27 | nextBestPath := Dequeue()
28 | vertices = strings.Split(nextBestPath.name, "-")
29 | if vertices[len(vertices)-1] != goalVtx {
30 | return g.traverseFurther(nextBestPath, goalVtx)
31 | }
32 |
33 | return nextBestPath
34 | }
35 |
--------------------------------------------------------------------------------
/algorithms/a_star/undirected_graph/priority_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Note - Lower priority value processes will be run first. Hence this is implemented using min heap.
4 |
5 | import (
6 | "fmt"
7 | "math"
8 | )
9 |
10 | var heap []*Node
11 |
12 | // Enqueue inserts a node in a heap
13 | func Enqueue(node *Node) {
14 | heap = append(heap, node)
15 | minHeapify()
16 | }
17 |
18 | func minHeapify() {
19 | idx := len(heap) - 1
20 | element := heap[idx]
21 | for idx > 0 {
22 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
23 | parent := heap[parentIdx]
24 | if element.value >= parent.value {
25 | break
26 | }
27 | heap[parentIdx] = element
28 | heap[idx] = parent
29 | idx = parentIdx
30 | }
31 | }
32 |
33 | // Dequeue will remove a node from heap
34 | func Dequeue() *Node {
35 | if len(heap) == 0 || heap[0] == nil {
36 | fmt.Println("\n-- Heap is empty. --")
37 | return nil
38 | }
39 | min := heap[0]
40 | end := heap[len(heap)-1]
41 | heap = heap[0 : len(heap)-1]
42 | if len(heap) > 0 {
43 | heap[0] = end
44 | bubbleDown()
45 | }
46 | return min
47 | }
48 |
49 | func bubbleDown() {
50 | idx := 0
51 | length := len(heap)
52 | element := heap[0]
53 | for {
54 | leftChildIdx := (2 * idx) + 1
55 | rightChildIdx := (2 * idx) + 2
56 | var leftChild, rightChild *Node
57 | var swap int
58 |
59 | if leftChildIdx < length {
60 | leftChild = heap[leftChildIdx]
61 | if leftChild.value < element.value {
62 | swap = leftChildIdx
63 | }
64 | }
65 | if rightChildIdx < length {
66 | rightChild = heap[rightChildIdx]
67 | if (rightChild.value < element.value && swap == 0) || (rightChild.value < leftChild.value && swap != 0) {
68 | swap = rightChildIdx
69 | }
70 | }
71 |
72 | if swap == 0 {
73 | break
74 | }
75 | heap[idx] = heap[swap]
76 | heap[swap] = element
77 | idx = swap
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/algorithms/activity_selection_gp/activity_selection_gp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type activity struct {
6 | start float64
7 | finish float64
8 | }
9 |
10 | // ActivitySelection selects the list of activities from given array
11 | func ActivitySelection() {
12 | j := 0
13 | for i := range activities {
14 | if i == 0 {
15 | selected = append(selected, i)
16 | j = i
17 | } else if activities[j].finish < activities[i].start {
18 | selected = append(selected, i)
19 | j = i
20 | }
21 | }
22 | }
23 |
24 | var n int
25 | var activities []activity
26 | var selected []int
27 |
28 | func init() {
29 | selected = make([]int, 0)
30 | }
31 |
32 | func main() {
33 | fmt.Println("\n-- Activity Selection Problem using Greedy Approach --")
34 |
35 | fmt.Print("\nEnter the number of activities: ")
36 | fmt.Scanf("%d\n", &n)
37 | activities = make([]activity, n)
38 |
39 | fmt.Println("Start entering starting and finishing times of each activities:")
40 | var temp float64
41 | for i := 0; i < n; i++ {
42 | fmt.Print("Start: ")
43 | fmt.Scanf("%f\n", &temp)
44 | activities[i].start = temp
45 | fmt.Print("Finish: ")
46 | fmt.Scanf("%f\n", &temp)
47 | activities[i].finish = temp
48 | }
49 |
50 | quicksort(0, n-1)
51 |
52 | ActivitySelection()
53 |
54 | fmt.Println("Selected activities are:")
55 | for i := range selected {
56 | fmt.Println(activities[selected[i]].start, activities[selected[i]].finish)
57 | }
58 | }
59 |
60 | // activities = []activity{
61 | // activity{start: 1, finish: 4},
62 | // activity{start: 3, finish: 5},
63 | // activity{start: 0, finish: 6},
64 | // activity{start: 5, finish: 7},
65 | // activity{start: 3, finish: 8},
66 | // activity{start: 5, finish: 9},
67 | // activity{start: 6, finish: 10},
68 | // activity{start: 8, finish: 11},
69 | // activity{start: 8, finish: 12},
70 | // activity{start: 2, finish: 13},
71 | // activity{start: 12, finish: 14},
72 | // }
73 | // n = 11
74 |
--------------------------------------------------------------------------------
/algorithms/activity_selection_gp/quick_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func partition(first, last int) int {
4 | pivot := activities[first].finish
5 | i := first
6 | j := last + 1
7 |
8 | for i < j {
9 | i++
10 | j--
11 | for activities[i].finish < pivot && i < last {
12 | i++
13 | }
14 | for activities[j].finish > pivot && j > first {
15 | j--
16 | }
17 | if i < j {
18 | activities[i].finish, activities[j].finish = activities[j].finish, activities[i].finish
19 | }
20 | }
21 | activities[j].finish, activities[first].finish = activities[first].finish, activities[j].finish
22 | return j
23 | }
24 |
25 | func quicksort(first, last int) {
26 | var sp int
27 | if first < last {
28 | sp = partition(first, last)
29 | quicksort(first, sp-1)
30 | quicksort(sp+1, last)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/algorithms/assembly_line_scheduling/assembly_scheduling.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | var assembly [][]int
9 | var transport [][]int
10 | var result [][]int
11 | var stations int
12 |
13 | func init() {
14 | assembly = make([][]int, 2)
15 | transport = make([][]int, 2)
16 | result = make([][]int, 2)
17 | }
18 |
19 | func main() {
20 | fmt.Println("\n-- Assembly Line Scheduling --")
21 | fmt.Print("Enter the number of stations in assembly line: ")
22 | fmt.Scanf("%d\n", &stations)
23 |
24 | fmt.Println("Start entering the costs:")
25 | var temp int
26 | for i := 0; i < 2; i++ {
27 | assembly[i] = make([]int, stations+2)
28 | for j := 0; j < stations+2; j++ {
29 | fmt.Print(i, "-", j, ": ")
30 | fmt.Scanf("%d\n", &temp)
31 | assembly[i][j] = temp
32 | }
33 | }
34 |
35 | fmt.Println("Start entering the transport costs:")
36 | for i := 0; i < 2; i++ {
37 | transport[i] = make([]int, stations+2)
38 | for j := 0; j < stations-1; j++ {
39 | fmt.Print(i+1, "-", j+1, ": ")
40 | fmt.Scanf("%d\n", &temp)
41 | transport[i][j+1] = temp
42 | }
43 | }
44 |
45 | assemblySchedule()
46 |
47 | fmt.Println("\nThe matrix formed during calculations:")
48 | fmt.Println(result[0])
49 | fmt.Println(result[1])
50 |
51 | if result[0][stations] < result[1][stations] {
52 | fmt.Println("\nCheapest way to assemble the product is:", result[0][stations])
53 | } else {
54 | fmt.Println("\nCheapest way to assemble the product is:", result[1][stations])
55 | }
56 | }
57 |
58 | func assemblySchedule() {
59 | i := 0
60 | result[i] = make([]int, stations+1)
61 | result[i+1] = make([]int, stations+1)
62 | for j := 0; j < stations; j++ {
63 | if j == 0 {
64 | result[i][j] = assembly[i][j] + assembly[i][j+1]
65 | result[i+1][j] = assembly[i+1][j] + assembly[i+1][j+1]
66 | } else {
67 | result[i][j] = int(math.Min(float64(result[i][j-1]+assembly[i][j+1]), float64(result[i+1][j-1]+transport[i+1][j]+assembly[i][j+1])))
68 | result[i+1][j] = int(math.Min(float64(result[i+1][j-1]+assembly[i+1][j+1]), float64(result[i][j-1]+transport[i][j]+assembly[i+1][j+1])))
69 | }
70 | check := j + 1
71 | if check == stations {
72 | result[i][j+1] = result[i][j] + assembly[i][j+2]
73 | result[i+1][j+1] = result[i+1][j] + assembly[i+1][j+2]
74 | }
75 | }
76 | }
77 |
78 | // assembly[0] = []int{2, 7, 9, 3, 4, 8, 4, 3}
79 | // assembly[1] = []int{4, 8, 5, 6, 4, 5, 7, 2}
80 |
81 | // transport[0] = []int{0, 2, 3, 1, 3, 4, 0, 0}
82 | // transport[1] = []int{0, 2, 1, 2, 2, 1, 0, 0}
83 |
--------------------------------------------------------------------------------
/algorithms/binary_reflected_gray_codes/brgc.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | )
7 |
8 | func main() {
9 | fmt.Println("\n-- Binary Reflected Gray Codes --")
10 | var value int
11 | fmt.Print("\nEnter a value: ")
12 | fmt.Scanf("%d\n", &value)
13 | if value < 1 {
14 | log.Fatal("Invalid value. Value must be greater than 0.")
15 | }
16 | l := BRGC(value)
17 | fmt.Println("Gray codes for", value, "bits are:")
18 | for i := 0; i < len(l); i++ {
19 | fmt.Println(l[i])
20 | }
21 | }
22 |
23 | // BRGC generates binary gray codes of given integer
24 | func BRGC(n int) []string {
25 |
26 | // return 0 and 1 as list if n == 1
27 | if n == 1 {
28 | return []string{"0", "1"}
29 | }
30 |
31 | // create list l1 by recursively calling on n-1
32 | l1 := BRGC(n - 1)
33 | l2 := make([]string, 0)
34 |
35 | // create list l2 in reverse order and add prefix 1 on each item
36 | for i := len(l1) - 1; i >= 0; i-- {
37 | l2 = append(l2, "1"+l1[i])
38 | }
39 |
40 | // add prefix 0 on each item of list l2
41 | for i := 0; i < len(l1); i++ {
42 | l1[i] = "0" + l1[i]
43 | }
44 |
45 | // append l2 to l1
46 | l1 = append(l1, l2...)
47 |
48 | // return generated list
49 | return l1
50 | }
51 |
--------------------------------------------------------------------------------
/algorithms/closest_pair_problem/cpp_brute_force/cpp_brute_force.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "log"
7 | "math"
8 | "os"
9 | "strconv"
10 | "strings"
11 | )
12 |
13 | // Point represents a point on a 2d plane having x, y coords
14 | type Point struct {
15 | x float64
16 | y float64
17 | }
18 |
19 | var arr []Point
20 |
21 | func init() {
22 |
23 | arr = make([]Point, 0)
24 |
25 | file, err := os.Open("sample.txt")
26 | if err != nil {
27 | log.Fatal(err)
28 | }
29 | defer file.Close()
30 |
31 | scanner := bufio.NewScanner(file)
32 | for scanner.Scan() {
33 | txt := scanner.Text()
34 | str := strings.Split(txt, " ")
35 |
36 | strx, err := strconv.ParseFloat(str[0], 64)
37 | if err != nil {
38 | log.Fatal(err)
39 | }
40 |
41 | stry, err := strconv.ParseFloat(str[1], 64)
42 | if err != nil {
43 | log.Fatal(err)
44 | }
45 |
46 | arr = append(arr, Point{x: strx, y: stry})
47 | }
48 |
49 | if err := scanner.Err(); err != nil {
50 | log.Fatal(err)
51 | }
52 | }
53 |
54 | func main() {
55 | fmt.Println("\n-- Closest Pair Problem using Brute Force Approach --")
56 | p, dist := ClosestPair(arr)
57 | fmt.Println("\nClosest pair of points are:", p[0], p[1], "whose distance is:", math.Sqrt(dist))
58 | }
59 |
60 | // ClosestPair finds two points in a given set of 2d points using BruteForce
61 | // Returns a point and distance between those two points
62 | func ClosestPair(pts []Point) ([]Point, float64) {
63 |
64 | dist := math.Inf(1)
65 | p := make([]Point, 2)
66 |
67 | for i := 0; i < len(pts)-1; i++ {
68 | for j := i + 1; j < len(pts); j++ {
69 | d := FindDist(pts[i], pts[j])
70 | if d < dist {
71 | dist = d
72 | p[0] = pts[i]
73 | p[1] = pts[j]
74 | }
75 | }
76 | }
77 | return p, dist
78 | }
79 |
80 | // FindDist finds distance between two points
81 | func FindDist(p1, p2 Point) float64 {
82 | return math.Pow(p2.x-p1.x, 2) + math.Pow(p2.y-p1.y, 2)
83 | }
84 |
--------------------------------------------------------------------------------
/algorithms/closest_pair_problem/cpp_brute_force/sample.txt:
--------------------------------------------------------------------------------
1 | 2 3
2 | 12 30
3 | 40 50
4 | 5 1
5 | 12 10
6 | 3 4
--------------------------------------------------------------------------------
/algorithms/closest_pair_problem/cpp_divide_conquer/sample.txt:
--------------------------------------------------------------------------------
1 | 10 7
2 | 30 12
3 | 8 1
4 | 37 18
5 | 14 15
6 | 6 40
7 | 50 20
8 | 19 2
9 | 4 50
10 | 3 20
--------------------------------------------------------------------------------
/algorithms/closest_pair_problem/cpp_divide_conquer/sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func compareX(p1, p2 Point) bool {
4 | return (p1.x < p2.x) || (p1.x == p2.x && p1.y > p2.y)
5 | }
6 |
7 | func compareY(p1, p2 Point) bool {
8 | return (p1.y < p2.y) || (p1.y == p2.y && p1.x < p2.x)
9 | }
10 |
11 | // Partition splits the arr into two arrays from pivot element
12 | func Partition(pts []Point, first, last int, compare func(p1, p2 Point) bool) int {
13 | pivot := pts[first]
14 | i := first
15 | j := last + 1
16 |
17 | for i < j {
18 | i++
19 | j--
20 | for compare(pts[i], pivot) && i < last {
21 | i++
22 | }
23 | for !compare(pts[j], pivot) && j > first {
24 | j--
25 | }
26 | if i < j {
27 | pts[i], pts[j] = pts[j], pts[i]
28 | }
29 | }
30 | pts[j], pts[first] = pts[first], pts[j]
31 | return j
32 | }
33 |
34 | // QuickSort algorithms sorts the array using the compare function passed
35 | func QuickSort(pts []Point, first, last int, compare func(p1, p2 Point) bool) {
36 | var sp int
37 | if first < last {
38 | sp = Partition(pts, first, last, compare)
39 | QuickSort(pts, first, sp-1, compare)
40 | QuickSort(pts, sp+1, last, compare)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/algorithms/combinations/with_r/combinations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("\n-- n C r Combinations with repetition --")
7 |
8 | var n, r int
9 | arr := make([]string, 0)
10 |
11 | fmt.Print("\nEnter the value of n: ")
12 | fmt.Scanf("%d\n", &n)
13 | fmt.Println("Start entering unique values of n:")
14 | for i := 0; i < n; i++ {
15 | var temp string
16 | fmt.Scanf("%s\n", &temp)
17 | arr = append(arr, temp)
18 | }
19 | fmt.Print("Enter the value of r: ")
20 | fmt.Scanf("%d\n", &r)
21 |
22 | data := make([]string, r)
23 |
24 | Combinations(arr, data, 0, n-1, 0, r)
25 | }
26 |
27 | // Combinations prints all possible nCr combinations of given array
28 | func Combinations(arr, data []string, start, end, index, r int) {
29 | if index == r {
30 | fmt.Println(data)
31 | return
32 | }
33 |
34 | for i := start; i <= end; i++ {
35 | data[index] = arr[i]
36 | Combinations(arr, data, i, end, index+1, r)
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/algorithms/combinations/without_r/combinations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("\n-- n C r Combinations without repetition --")
7 |
8 | var n, r int
9 | arr := make([]string, 0)
10 |
11 | fmt.Print("\nEnter the value of n: ")
12 | fmt.Scanf("%d\n", &n)
13 | fmt.Println("Start entering unique values of n:")
14 | for i := 0; i < n; i++ {
15 | var temp string
16 | fmt.Scanf("%s\n", &temp)
17 | arr = append(arr, temp)
18 | }
19 | fmt.Print("Enter the value of r: ")
20 | fmt.Scanf("%d\n", &r)
21 |
22 | data := make([]string, r)
23 |
24 | Combinations(arr, data, 0, n-1, 0, r)
25 | }
26 |
27 | // Combinations prints all possible nCr combinations of given array
28 | func Combinations(arr, data []string, start, end, index, r int) {
29 | if index == r {
30 | fmt.Println(data)
31 | return
32 | }
33 |
34 | for i := start; i <= end && end-i+1 >= r-index; i++ {
35 | data[index] = arr[i]
36 | Combinations(arr, data, i+1, end, index+1, r)
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_brute_force/ch_brute_force.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "log"
7 | "os"
8 | "strconv"
9 | "strings"
10 | )
11 |
12 | // Point represents a point on a 2d plane having x, y coords
13 | type Point struct {
14 | x float64
15 | y float64
16 | }
17 |
18 | var arr []Point
19 |
20 | // pointInConvex keeps a simple check
21 | // whether a given point is considered in convex set or not
22 | var pointInConvex map[string]bool
23 |
24 | func init() {
25 | arr = make([]Point, 0)
26 | pointInConvex = make(map[string]bool)
27 |
28 | file, err := os.Open("sample.txt")
29 | if err != nil {
30 | log.Fatal(err)
31 | }
32 | defer file.Close()
33 |
34 | scanner := bufio.NewScanner(file)
35 | for scanner.Scan() {
36 | txt := scanner.Text()
37 | str := strings.Split(txt, " ")
38 |
39 | strx, err := strconv.ParseFloat(str[0], 64)
40 | if err != nil {
41 | log.Fatal(err)
42 | }
43 |
44 | stry, err := strconv.ParseFloat(str[1], 64)
45 | if err != nil {
46 | log.Fatal(err)
47 | }
48 |
49 | arr = append(arr, Point{x: strx, y: stry})
50 | }
51 |
52 | if err := scanner.Err(); err != nil {
53 | log.Fatal(err)
54 | }
55 | }
56 |
57 | func main() {
58 | fmt.Println("\n-- Convex Hull Brute Force Technique --")
59 | ch := ConvexHull()
60 | ch = SortConvexPoints(ch)
61 | for i := 0; i < len(ch); i++ {
62 | fmt.Println(ch[i])
63 | }
64 | }
65 |
66 | // ConvexHull finds required set of points which forms a convex
67 | func ConvexHull() []Point {
68 | newArr := make([]Point, 0)
69 |
70 | for i := 0; i < len(arr)-1; i++ {
71 | for j := i + 1; j < len(arr); j++ {
72 | flag := IsConvex(arr[i], arr[j])
73 |
74 | if !flag {
75 | continue
76 | }
77 |
78 | // float64 to string
79 | xi := fmt.Sprintf("%f\n", arr[i].x)
80 | yi := fmt.Sprintf("%f\n", arr[i].y)
81 | xj := fmt.Sprintf("%f\n", arr[j].x)
82 | yj := fmt.Sprintf("%f\n", arr[j].y)
83 |
84 | //string of x[i] y[i]
85 | strI := xi + yi
86 | //string of x[j] y[j]
87 | strJ := xj + yj
88 |
89 | if !pointInConvex[strI] {
90 | newArr = append(newArr, arr[i])
91 | pointInConvex[strI] = true
92 | }
93 |
94 | if !pointInConvex[strJ] {
95 | newArr = append(newArr, arr[j])
96 | pointInConvex[strJ] = true
97 | }
98 | }
99 | }
100 | return newArr
101 | }
102 |
103 | // IsConvex checks whether the given two points should be considered in the solution
104 | func IsConvex(p1, p2 Point) bool {
105 | flag := float64(0)
106 | a := p2.y - p1.y
107 | b := p1.x - p2.x
108 | c := p1.x*p2.y - p1.y*p2.x
109 |
110 | for i := 0; i < len(arr); i++ {
111 | lhs := a*arr[i].x + b*arr[i].y - c
112 | if lhs == 0 {
113 | check := IsLongestPair(p1, p2, arr[i])
114 | if !check {
115 | return false
116 | }
117 | }
118 | if flag != 0 && lhs != 0 && !((lhs < 0 && flag < 0) || (lhs > 0 && flag > 0)) {
119 | return false
120 | }
121 | if flag == 0 {
122 | flag = lhs
123 | }
124 | }
125 | return true
126 | }
127 |
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_brute_force/helpers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "math"
5 | "sort"
6 | )
7 |
8 | // IsLongestPair checks whether the given first two set of points (p1, p2) have longest distance or not
9 | // The main idea is not to select all given points in question that lies on the same line
10 | func IsLongestPair(p1, p2, p3 Point) bool {
11 | d12 := math.Pow(p1.x-p2.x, 2) + math.Pow(p1.y-p2.y, 2)
12 | d13 := math.Pow(p1.x-p3.x, 2) + math.Pow(p1.y-p3.y, 2)
13 | d23 := math.Pow(p2.x-p3.x, 2) + math.Pow(p2.y-p3.y, 2)
14 | if d12 >= d13 && d12 >= d23 {
15 | return true
16 | }
17 | return false
18 | }
19 |
20 | // FindAngle finds an angle between lines formed by p1p2 and p2p3 represented as ∠p1p2p3
21 | //
22 | // i.e. angle formed at point p2
23 | func FindAngle(p1, p2, p3 Point) float64 {
24 | deg1 := int(((math.Atan2(p1.x-p2.x, p1.y-p2.y)*180)/math.Pi)+360) % 360
25 | deg2 := int(((math.Atan2(p3.x-p2.x, p3.y-p2.y)*180)/math.Pi)+360) % 360
26 | return float64(deg1 - deg2)
27 | }
28 |
29 | // SortConvexPoints sorts points of convex polygon in clockwise fashion
30 | func SortConvexPoints(pts []Point) []Point {
31 |
32 | // initializations
33 | newPts := make([]Point, 0)
34 | temp := make(map[float64]Point)
35 | center := Point{x: 0, y: 0}
36 | p1 := pts[0]
37 |
38 | // find a point within the convex polygon
39 | for i := 0; i < len(pts); i++ {
40 | center.x += pts[i].x
41 | center.y += pts[i].y
42 | }
43 |
44 | center.x /= float64(len(pts))
45 | center.y /= float64(len(pts))
46 |
47 | // find angle of each points formed at center point
48 | for i := 0; i < len(pts); i++ {
49 | angle := FindAngle(pts[i], center, p1)
50 | temp[angle] = pts[i]
51 | }
52 |
53 | // get all keys (angles)
54 | keys := make([]float64, 0)
55 |
56 | for i := range temp {
57 | keys = append(keys, i)
58 | }
59 |
60 | // sort these keys
61 | sort.Float64s(keys)
62 |
63 | // using map access each points in sorted fashion using keys
64 | for i := 0; i < len(keys); i++ {
65 | newPts = append(newPts, temp[keys[i]])
66 | }
67 |
68 | return newPts
69 | }
70 |
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_brute_force/sample.txt:
--------------------------------------------------------------------------------
1 | 0 0
2 | 0 1
3 | 0 2
4 | 0 3
5 | 1 0
6 | 1 1
7 | 1 2
8 | 1 3
9 | 2 0
10 | 2 1
11 | 2 2
12 | 2 3
13 | 2 4
14 | 2 5
15 | 2 6
16 | 2 7
17 | 2 8
18 | 2 9
19 | 3 0
20 | 3 1
21 | 3 2
22 | 3 3
23 | 4 0
24 | 4 1
25 | 4 2
26 | 4 3
27 | 4 4
28 | 5 1
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_divide_conquer/helpers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "math"
5 | "sort"
6 | )
7 |
8 | // FindDist finds distance between two points on a plane
9 | func FindDist(p1, p2 Point) float64 {
10 | return math.Pow(p1.x-p2.x, 2) + math.Pow(p1.y-p2.y, 2)
11 | }
12 |
13 | // FindSide returns an integer specifying whether the point p3 is on left, right or on the line specified by points p1 and p2.
14 | //
15 | // Returns:
16 | //
17 | // -1 if point p3 is on the left side.
18 | //
19 | // 0 if point p3 is on the line.
20 | //
21 | // 1 if point p3 is on the right side.
22 | func FindSide(p1, p2, p3 Point) int {
23 | area := p1.x*p2.y + p3.x*p1.y + p2.x*p3.y - (p3.x*p2.y + p2.x*p1.y + p1.x*p3.y)
24 | if area > 0 {
25 | return 1
26 | }
27 | if area < 0 {
28 | return -1
29 | }
30 | return 0
31 | }
32 |
33 | // IsInside checks whether a given point p4 is inside a traingle of points p1, p2, p3 or not.
34 | //
35 | // Returns:
36 | //
37 | // true if it is inside the triangle
38 | //
39 | // false if it otherwise
40 | func IsInside(p1, p2, p3, p4 Point) bool {
41 |
42 | var a0, a1, a2, a3 float64
43 |
44 | a0 = (p1.x*(p2.y-p3.y) + p2.x*(p3.y-p1.y) + p3.x*(p1.y-p2.y)) / 2
45 | a1 = (p1.x*(p2.y-p4.y) + p2.x*(p4.y-p1.y) + p4.x*(p1.y-p2.y)) / 2
46 | a2 = (p2.x*(p3.y-p4.y) + p3.x*(p4.y-p2.y) + p4.x*(p2.y-p3.y)) / 2
47 | a3 = (p1.x*(p3.y-p4.y) + p3.x*(p4.y-p1.y) + p4.x*(p1.y-p3.y)) / 2
48 |
49 | // removing -ve sign if any
50 | if a0 < 0 {
51 | a0 = -1 * a0
52 | }
53 | if a1 < 0 {
54 | a1 = -1 * a1
55 | }
56 | if a2 < 0 {
57 | a2 = -1 * a2
58 | }
59 | if a3 < 0 {
60 | a3 = -1 * a3
61 | }
62 |
63 | if math.Round(a0) == math.Round(a1+a2+a3) {
64 | return true
65 | }
66 | return false
67 | }
68 |
69 | // FindAngle finds an angle between lines formed by p1p2 and p2p3 represented as ∠p1p2p3
70 | //
71 | // i.e. angle formed at point p2
72 | func FindAngle(p1, p2, p3 Point) float64 {
73 | deg1 := int(((math.Atan2(p1.x-p2.x, p1.y-p2.y)*180)/math.Pi)+360) % 360
74 | deg2 := int(((math.Atan2(p3.x-p2.x, p3.y-p2.y)*180)/math.Pi)+360) % 360
75 | return float64(deg1 - deg2)
76 | }
77 |
78 | // SortConvexPoints sorts points of convex polygon in clockwise fashion
79 | func SortConvexPoints(pts []Point) []Point {
80 |
81 | // initializations
82 | newPts := make([]Point, 0)
83 | temp := make(map[float64]Point)
84 | center := Point{x: 0, y: 0}
85 | p1 := pts[0]
86 |
87 | // find a point within the convex polygon
88 | for i := 0; i < len(pts); i++ {
89 | center.x += pts[i].x
90 | center.y += pts[i].y
91 | }
92 |
93 | center.x /= float64(len(pts))
94 | center.y /= float64(len(pts))
95 |
96 | // find angle of each points formed at center point
97 | for i := 0; i < len(pts); i++ {
98 | angle := FindAngle(pts[i], center, p1)
99 | temp[angle] = pts[i]
100 | }
101 |
102 | // get all keys (angles)
103 | keys := make([]float64, 0)
104 |
105 | for i := range temp {
106 | keys = append(keys, i)
107 | }
108 |
109 | // sort these keys
110 | sort.Float64s(keys)
111 |
112 | // using map access each points in sorted fashion using keys
113 | for i := 0; i < len(keys); i++ {
114 | newPts = append(newPts, temp[keys[i]])
115 | }
116 |
117 | return newPts
118 | }
119 |
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_divide_conquer/sample.txt:
--------------------------------------------------------------------------------
1 | 0 0
2 | 2 0
3 | 0 3
4 | 3 2
5 | 3 3
6 | 0 2
7 | 4 1
8 | 5 1
9 | 2 5
10 | 2 6
11 | 1 1
12 | 1 2
13 | 1 3
14 | 1 0
15 | 2 1
16 | 2 2
17 | 2 3
18 | 2 4
19 | 0 1
20 | 2 7
21 | 4 3
22 | 4 4
23 | 2 8
24 | 2 9
25 | 3 0
26 | 3 1
27 | 4 0
28 | 4 2
--------------------------------------------------------------------------------
/algorithms/convex_hull/ch_divide_conquer/sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func merge(l, m, r int) {
4 | var i, j, k int
5 | nl := m - l + 1
6 | nr := r - m
7 | var left, right []Point
8 |
9 | for i = 0; i < nl; i++ {
10 | left = append(left, arr[l+i])
11 | }
12 |
13 | for j = 0; j < nr; j++ {
14 | right = append(right, arr[m+1+j])
15 | }
16 |
17 | i = 0
18 | j = 0
19 | k = l
20 |
21 | for i < nl && j < nr {
22 | if (left[i].x < right[j].x) || (left[i].x == right[j].x && left[i].y < right[j].y) {
23 | arr[k] = left[i]
24 | i++
25 | k++
26 | } else {
27 | arr[k] = right[j]
28 | j++
29 | k++
30 | }
31 | }
32 |
33 | for i < nl {
34 | arr[k] = left[i]
35 | i++
36 | k++
37 | }
38 | for j < nr {
39 | arr[k] = right[j]
40 | j++
41 | k++
42 | }
43 | }
44 |
45 | // MergeSort sorts list of points in non decreasing order of x values and ties resolved with y values sorted in non decreasing order
46 | func MergeSort(l, r int) {
47 | var mid int
48 | if l < r {
49 | mid = (l + r) / 2
50 | MergeSort(l, mid)
51 | MergeSort(mid+1, r)
52 | merge(l, mid, r)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/infix_postfix/infix_postfix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // InToPos converts an infix expression to postfix expression
6 | func InToPos() {
7 | if !validate(expression) {
8 | fmt.Println("\n-- Invalid expression --")
9 | return
10 | }
11 | postfix := ""
12 | stack = append(stack, "N")
13 | for i := range expression {
14 | char := string(expression[i])
15 | if (expression[i] >= 65 && expression[i] <= 90) || (expression[i] >= 97 && expression[i] <= 122) {
16 | postfix += char
17 | } else if char == "(" {
18 | stack = append(stack, char)
19 | } else if char == ")" {
20 | for stack[len(stack)-1] != "N" && stack[len(stack)-1] != "(" {
21 | newChar := stack[len(stack)-1]
22 | stack = stack[0 : len(stack)-1]
23 | postfix += newChar
24 | }
25 | if stack[len(stack)-1] == "(" {
26 | stack = stack[0 : len(stack)-1]
27 | }
28 | } else {
29 | for stack[len(stack)-1] != "N" && Prec(stack[len(stack)-1]) >= Prec(char) {
30 | newChar := stack[len(stack)-1]
31 | stack = stack[0 : len(stack)-1]
32 | postfix += newChar
33 | }
34 | stack = append(stack, char)
35 | }
36 | }
37 | for stack[len(stack)-1] != "N" {
38 | newChar := stack[len(stack)-1]
39 | stack = stack[0 : len(stack)-1]
40 | postfix += newChar
41 | }
42 | fmt.Println("\n" + postfix)
43 | }
44 |
45 | var stack []string
46 | var expression string
47 |
48 | func main() {
49 | fmt.Println("\n-- Infix to Postfix expression conversion --")
50 | i := 0
51 | for i == 0 {
52 | fmt.Print("\nEnter the expression: ")
53 | fmt.Scanf("%s\n", &expression)
54 | InToPos()
55 | var choice string
56 | fmt.Print("\nDo you want to continue y/n? ")
57 | fmt.Scanf("%s\n", &choice)
58 | if choice == "N" || choice == "n" {
59 | break
60 | } else if choice == "Y" || choice == "y" {
61 | continue
62 | } else {
63 | fmt.Println("Command not recognized.")
64 | }
65 | }
66 | }
67 |
68 | // Prec will return a precedence of a given operator
69 | func Prec(c string) int {
70 | if c == "^" {
71 | return 3
72 | } else if c == "*" || c == "/" {
73 | return 2
74 | } else if c == "+" || c == "-" {
75 | return 1
76 | }
77 | return -1
78 | }
79 |
80 | func isOperator(s string) bool {
81 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
82 | return true
83 | }
84 | return false
85 | }
86 |
87 | func validate(c string) bool {
88 | var check int
89 | for i := range c {
90 | if isOperator(string(c[i])) || string(c[i]) == ")" {
91 | check += -1
92 | } else {
93 | check++
94 | }
95 | }
96 | return check == 1
97 | }
98 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/infix_prefix/infix_prefix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // InToPos converts an infix expression to prefix expression
8 | func InToPos(expression string) string {
9 | postfix := ""
10 | stack = append(stack, "N")
11 | for i := range expression {
12 | char := string(expression[i])
13 | if (expression[i] >= 65 && expression[i] <= 90) || (expression[i] >= 97 && expression[i] <= 122) {
14 | postfix += char
15 | } else if char == "(" {
16 | stack = append(stack, char)
17 | } else if char == ")" {
18 | for stack[len(stack)-1] != "N" && stack[len(stack)-1] != "(" {
19 | newChar := stack[len(stack)-1]
20 | stack = stack[0 : len(stack)-1]
21 | postfix += newChar
22 | }
23 | if stack[len(stack)-1] == "(" {
24 | stack = stack[0 : len(stack)-1]
25 | }
26 | } else {
27 | for stack[len(stack)-1] != "N" && Prec(stack[len(stack)-1]) >= Prec(char) {
28 | newChar := stack[len(stack)-1]
29 | stack = stack[0 : len(stack)-1]
30 | postfix += newChar
31 | }
32 | stack = append(stack, char)
33 | }
34 | }
35 | for stack[len(stack)-1] != "N" {
36 | newChar := stack[len(stack)-1]
37 | stack = stack[0 : len(stack)-1]
38 | postfix += newChar
39 | }
40 | return postfix
41 | }
42 |
43 | // InToPre will reverse the expression and will call postfix on it
44 | // will then reverse again the returned expression from postfix call
45 | func InToPre() {
46 | if !validate(inputExp) {
47 | fmt.Println("\n-- Invalid expression --")
48 | return
49 | }
50 | reverseStr := reverse(inputExp)
51 | postfix := InToPos(reverseStr)
52 | prefix := reverse(postfix)
53 | fmt.Println("\n" + prefix)
54 | }
55 |
56 | var stack []string
57 | var inputExp string
58 |
59 | func main() {
60 | fmt.Println("\n-- Infix to Prefix expression conversion --")
61 | i := 0
62 | for i == 0 {
63 | fmt.Print("\nEnter the expression: ")
64 | fmt.Scanf("%s\n", &inputExp)
65 | InToPre()
66 | var choice string
67 | fmt.Print("\nDo you want to continue y/n? ")
68 | fmt.Scanf("%s\n", &choice)
69 | if choice == "N" || choice == "n" {
70 | break
71 | } else if choice == "Y" || choice == "y" {
72 | continue
73 | } else {
74 | fmt.Println("Command not recognized.")
75 | }
76 | }
77 | }
78 |
79 | // Prec will return a precedence of a given operator
80 | func Prec(c string) int {
81 | if c == "^" {
82 | return 3
83 | } else if c == "*" || c == "/" {
84 | return 2
85 | } else if c == "+" || c == "-" {
86 | return 1
87 | }
88 | return 0
89 | }
90 |
91 | func isOperator(s string) bool {
92 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
93 | return true
94 | }
95 | return false
96 | }
97 |
98 | func reverse(s string) string {
99 | reverseStr := ""
100 | j := len(s) - 1
101 | for j != -1 {
102 | if string(s[j]) == ")" {
103 | reverseStr += "("
104 | } else if string(s[j]) == "(" {
105 | reverseStr += ")"
106 | } else {
107 | reverseStr += string(s[j])
108 | }
109 | j--
110 | }
111 | return reverseStr
112 | }
113 |
114 | func validate(c string) bool {
115 | var check int
116 | for i := range c {
117 | if isOperator(string(c[i])) || string(c[i]) == ")" {
118 | check += -1
119 | } else {
120 | check++
121 | }
122 | }
123 | return check == 1
124 | }
125 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/postfix_infix/postfix_infix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // PosToIn will convert a given Postfix notation to Infix
6 | func PosToIn() {
7 | if !validate(expression) {
8 | fmt.Println("\n-- Invalid expression --")
9 | return
10 | }
11 | for i := range expression {
12 | char := string(expression[i])
13 | if (expression[i] >= 65 && expression[i] <= 90) || (expression[i] >= 97 && expression[i] <= 122) {
14 | stack = append(stack, char)
15 | } else {
16 | operand1 := stack[len(stack)-1] // read top of stack
17 | stack = stack[0 : len(stack)-1] // pop from stack
18 | operand2 := stack[len(stack)-1] // read top of stack
19 | stack = stack[0 : len(stack)-1] // pop from stack
20 | temp := "(" + operand2 + char + operand1 + ")"
21 | stack = append(stack, temp)
22 | }
23 | }
24 | infix := stack[len(stack)-1] // read top of stack which is the final infix notation
25 | fmt.Println("\n" + infix)
26 | }
27 |
28 | var stack []string
29 | var expression string
30 |
31 | func main() {
32 | fmt.Println("\n-- Postfix to Infix expression conversion --")
33 | i := 0
34 | for i == 0 {
35 | fmt.Print("\nEnter the expression: ")
36 | fmt.Scanf("%s\n", &expression)
37 | PosToIn()
38 | var choice string
39 | fmt.Print("\nDo you want to continue y/n? ")
40 | fmt.Scanf("%s\n", &choice)
41 | if choice == "N" || choice == "n" {
42 | break
43 | } else if choice == "Y" || choice == "y" {
44 | continue
45 | } else {
46 | fmt.Println("Command not recognized.")
47 | }
48 | }
49 | }
50 |
51 | func isOperator(s string) bool {
52 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
53 | return true
54 | }
55 | return false
56 | }
57 |
58 | func validate(c string) bool {
59 | var check int
60 | for i := range c {
61 | if isOperator(string(c[i])) || string(c[i]) == ")" {
62 | check += -1
63 | } else {
64 | check++
65 | }
66 | }
67 | return check == 1
68 | }
69 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/postfix_prefix/postfix_prefix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // PosToPre will convert a given Postfix notation to Prefix
6 | func PosToPre() {
7 | if !validate(expression) {
8 | fmt.Println("\n-- Invalid expression --")
9 | return
10 | }
11 | for i := range expression {
12 | char := string(expression[i])
13 | if (expression[i] >= 65 && expression[i] <= 90) || (expression[i] >= 97 && expression[i] <= 122) {
14 | stack = append(stack, char)
15 | } else {
16 | operand1 := stack[len(stack)-1] // read top of stack
17 | stack = stack[0 : len(stack)-1] // pop from stack
18 | operand2 := stack[len(stack)-1] // read top of stack
19 | stack = stack[0 : len(stack)-1] // pop from stack
20 | temp := char + operand2 + operand1
21 | stack = append(stack, temp)
22 | }
23 | }
24 | infix := stack[len(stack)-1] // read top of stack which is the final infix notation
25 | fmt.Println("\n" + infix)
26 | }
27 |
28 | var stack []string
29 | var expression string
30 |
31 | func main() {
32 | fmt.Println("\n-- Postfix to Prefix expression conversion --")
33 | i := 0
34 | for i == 0 {
35 | fmt.Print("\nEnter the expression: ")
36 | fmt.Scanf("%s\n", &expression)
37 | PosToPre()
38 | var choice string
39 | fmt.Print("\nDo you want to continue y/n? ")
40 | fmt.Scanf("%s\n", &choice)
41 | if choice == "N" || choice == "n" {
42 | break
43 | } else if choice == "Y" || choice == "y" {
44 | continue
45 | } else {
46 | fmt.Println("Command not recognized.")
47 | }
48 | }
49 | }
50 |
51 | func isOperator(s string) bool {
52 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
53 | return true
54 | }
55 | return false
56 | }
57 |
58 | func validate(c string) bool {
59 | var check int
60 | for i := range c {
61 | if isOperator(string(c[i])) || string(c[i]) == ")" {
62 | check += -1
63 | } else {
64 | check++
65 | }
66 | }
67 | return check == 1
68 | }
69 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/prefix_infix/prefix_infix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // PreToIn will convert a given Prefix notation to Infix
6 | func PreToIn() {
7 | if !validate(expression) {
8 | fmt.Println("\n-- Invalid expression --")
9 | return
10 | }
11 | str := reverse(expression)
12 | for i := range str {
13 | char := string(str[i])
14 | if (str[i] >= 65 && str[i] <= 90) || (str[i] >= 97 && str[i] <= 122) {
15 | stack = append(stack, char)
16 | } else {
17 | operand1 := stack[len(stack)-1] // read top of stack
18 | stack = stack[0 : len(stack)-1] // pop from stack
19 | operand2 := stack[len(stack)-1] // read top of stack
20 | stack = stack[0 : len(stack)-1] // pop from stack
21 | temp := "(" + operand1 + char + operand2 + ")"
22 | stack = append(stack, temp)
23 | }
24 | }
25 | infix := stack[len(stack)-1] // read top of stack which is the final infix notation
26 | fmt.Println("\n" + infix)
27 | }
28 |
29 | var stack []string
30 | var expression string
31 |
32 | func main() {
33 | fmt.Println("\n-- Prefix to Infix expression conversion --")
34 | i := 0
35 | for i == 0 {
36 | fmt.Print("\nEnter the expression: ")
37 | fmt.Scanf("%s\n", &expression)
38 | PreToIn()
39 | var choice string
40 | fmt.Print("\nDo you want to continue y/n? ")
41 | fmt.Scanf("%s\n", &choice)
42 | if choice == "N" || choice == "n" {
43 | break
44 | } else if choice == "Y" || choice == "y" {
45 | continue
46 | } else {
47 | fmt.Println("Command not recognized.")
48 | }
49 | }
50 | }
51 |
52 | func reverse(s string) string {
53 | reverseStr := ""
54 | j := len(s) - 1
55 | for j != -1 {
56 | if string(s[j]) == ")" {
57 | reverseStr += "("
58 | } else if string(s[j]) == "(" {
59 | reverseStr += ")"
60 | } else {
61 | reverseStr += string(s[j])
62 | }
63 | j--
64 | }
65 | return reverseStr
66 | }
67 |
68 | func isOperator(s string) bool {
69 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
70 | return true
71 | }
72 | return false
73 | }
74 |
75 | func validate(c string) bool {
76 | var check int
77 | for i := range c {
78 | if isOperator(string(c[i])) || string(c[i]) == ")" {
79 | check += -1
80 | } else {
81 | check++
82 | }
83 | }
84 | return check == 1
85 | }
86 |
--------------------------------------------------------------------------------
/algorithms/expression_conversions/prefix_postfix/prefix_postfix.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // PreToPos will convert a given Prefix notation to Postfix
6 | func PreToPos() {
7 | if !validate(expression) {
8 | fmt.Println("\n-- Invalid expression --")
9 | return
10 | }
11 | str := reverse(expression)
12 | for i := range str {
13 | char := string(str[i])
14 | if (str[i] >= 65 && str[i] <= 90) || (str[i] >= 97 && str[i] <= 122) {
15 | stack = append(stack, char)
16 | } else {
17 | operand1 := stack[len(stack)-1] // read top of stack
18 | stack = stack[0 : len(stack)-1] // pop from stack
19 | operand2 := stack[len(stack)-1] // read top of stack
20 | stack = stack[0 : len(stack)-1] // pop from stack
21 | temp := operand1 + operand2 + char
22 | stack = append(stack, temp)
23 | }
24 | }
25 | infix := stack[len(stack)-1] // read top of stack which is the final infix notation
26 | fmt.Println("\n" + infix)
27 | }
28 |
29 | var stack []string
30 | var expression string
31 |
32 | func main() {
33 | fmt.Println("\n-- Prefix to Postfix expression conversion --")
34 | i := 0
35 | for i == 0 {
36 | fmt.Print("\nEnter the expression: ")
37 | fmt.Scanf("%s\n", &expression)
38 | PreToPos()
39 | var choice string
40 | fmt.Print("\nDo you want to continue y/n? ")
41 | fmt.Scanf("%s\n", &choice)
42 | if choice == "N" || choice == "n" {
43 | break
44 | } else if choice == "Y" || choice == "y" {
45 | continue
46 | } else {
47 | fmt.Println("Command not recognized.")
48 | }
49 | }
50 | }
51 |
52 | func reverse(s string) string {
53 | reverseStr := ""
54 | j := len(s) - 1
55 | for j != -1 {
56 | if string(s[j]) == ")" {
57 | reverseStr += "("
58 | } else if string(s[j]) == "(" {
59 | reverseStr += ")"
60 | } else {
61 | reverseStr += string(s[j])
62 | }
63 | j--
64 | }
65 | return reverseStr
66 | }
67 |
68 | func isOperator(s string) bool {
69 | if s == "^" || s == "*" || s == "/" || s == "+" || s == "-" {
70 | return true
71 | }
72 | return false
73 | }
74 |
75 | func validate(c string) bool {
76 | var check int
77 | for i := range c {
78 | if isOperator(string(c[i])) || string(c[i]) == ")" {
79 | check += -1
80 | } else {
81 | check++
82 | }
83 | }
84 | return check == 1
85 | }
86 |
--------------------------------------------------------------------------------
/algorithms/gcd/README.md:
--------------------------------------------------------------------------------
1 | #### GCD - Greatest Common Divisor
2 |
3 | Euclid of Alexandria outlined an algorithm for solving this problem in one of the volumes of his Elements most famous for its systematic exposition of geometry. In modern terms, Euclid’s algorithm is based on applying repeatedly the equality
4 |
5 | gcd(m, n) = gcd(n, m mod n)
6 |
7 | For e.g:
8 |
9 | gcd(60, 24) = gcd(24, 12) = gcd(12, 0) = 12
10 |
--------------------------------------------------------------------------------
/algorithms/gcd/gcd.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var n, m int
7 | fmt.Println("-- GCD --")
8 | fmt.Print("Enter the first number: ")
9 | fmt.Scanf("%d\n", &n)
10 | fmt.Print("Enter the second number: ")
11 | fmt.Scanf("%d\n", &m)
12 | var gcd int
13 | if n < m {
14 | gcd = findGCD(m, n)
15 | } else {
16 | gcd = findGCD(n, m)
17 | }
18 | fmt.Println("GCD of given numbers is:", gcd)
19 | }
20 |
21 | func findGCD(m, n int) int {
22 | if n == 0 {
23 | return m
24 | }
25 | return findGCD(n, m%n)
26 | }
27 |
--------------------------------------------------------------------------------
/algorithms/graphs/articulation_point_detection/articulation_point.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | g := make(graph)
7 | i := 0
8 | for i == 0 {
9 | fmt.Println("\n1. ADD A VERTEX")
10 | fmt.Println("2. ADD AN EDGE")
11 | fmt.Println("3. DETECT ARTICULATION POINTS")
12 | fmt.Println("4. SIMPLE DISPLAY")
13 | fmt.Println("5. EXIT")
14 | var choice int
15 | fmt.Print("Enter your choice: ")
16 | fmt.Scanf("%d\n", &choice)
17 | switch choice {
18 | case 1:
19 | g.addVertex()
20 | case 2:
21 | g.addEdge()
22 | case 3:
23 | result := g.findArticulationPoints()
24 | if len(result) != 0 {
25 | fmt.Println("\n-- Articulation point/s exists in a given graph. --")
26 | for i := range result {
27 | if result[i] {
28 | fmt.Println(i)
29 | }
30 | }
31 | } else {
32 | fmt.Println("\n -- No articulation point/s exists in a given graph. --")
33 | }
34 | case 4:
35 | g.simpleDisplay()
36 | default:
37 | fmt.Println("Command not recognized.")
38 | }
39 | }
40 | }
41 |
42 | // c, d, h
43 | // g.addVertexToGraph("a")
44 | // g.addVertexToGraph("b")
45 | // g.addVertexToGraph("c")
46 | // g.addVertexToGraph("d")
47 | // g.addVertexToGraph("e")
48 | // g.addVertexToGraph("f")
49 | // g.addVertexToGraph("g")
50 | // g.addVertexToGraph("h")
51 | // g.addVertexToGraph("i")
52 | // g.addEdgeToGraph("a", "b")
53 | // g.addEdgeToGraph("b", "c")
54 | // g.addEdgeToGraph("c", "a")
55 | // g.addEdgeToGraph("c", "d")
56 | // g.addEdgeToGraph("d", "e")
57 | // g.addEdgeToGraph("e", "f")
58 | // g.addEdgeToGraph("f", "g")
59 | // g.addEdgeToGraph("g", "d")
60 | // g.addEdgeToGraph("c", "h")
61 | // g.addEdgeToGraph("h", "i")
62 |
--------------------------------------------------------------------------------
/algorithms/graphs/articulation_point_detection/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type graph map[string][]string
6 |
7 | func (g graph) addVertexToGraph(vtx string) {
8 | if g[vtx] != nil {
9 | fmt.Println("\n-- Vertex already exists. --")
10 | return
11 | }
12 | g[vtx] = make([]string, 0)
13 | }
14 |
15 | func (g graph) addEdgeToGraph(fromVtx, toVtx string) {
16 | if g[fromVtx] == nil { // check if initial vertex exists
17 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
18 | return
19 | }
20 | for i := range g[fromVtx] { // check if edge already exists
21 | if g[fromVtx][i] == toVtx {
22 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
23 | return
24 | }
25 | }
26 | if g[toVtx] == nil { // create new destination vertext if it does not exists
27 | g[toVtx] = make([]string, 0)
28 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
29 | }
30 |
31 | g[fromVtx] = append(g[fromVtx], toVtx)
32 | g[toVtx] = append(g[toVtx], fromVtx)
33 | }
34 |
35 | func (g graph) addVertex() {
36 | var vtxName string
37 | fmt.Print("Enter the name of vertex: ")
38 | fmt.Scanf("%s\n", &vtxName)
39 | g.addVertexToGraph(vtxName)
40 | }
41 |
42 | func (g graph) addEdge() {
43 | var fromVtx, toVtx string
44 | fmt.Print("Enter the initial vertex name: ")
45 | fmt.Scanf("%s\n", &fromVtx)
46 | fmt.Print("Enter the destination vertex name: ")
47 | fmt.Scanf("%s\n", &toVtx)
48 | g.addEdgeToGraph(fromVtx, toVtx)
49 | }
50 |
--------------------------------------------------------------------------------
/algorithms/graphs/articulation_point_detection/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | var id float64
9 | var outEdgeCount float64
10 | var ids map[string]float64
11 | var low map[string]float64
12 | var isArt map[string]bool
13 |
14 | func init() {
15 | id = 0
16 | outEdgeCount = 0
17 | ids = make(map[string]float64)
18 | low = make(map[string]float64)
19 | isArt = make(map[string]bool)
20 | }
21 |
22 | // DFS traverses a graph using dfs technique
23 | func (g graph) findArticulationPoints() map[string]bool {
24 | visited := make(map[string]bool)
25 | if len(g) == 0 {
26 | fmt.Println("\n-- Graph is empty. --")
27 | return nil
28 | }
29 | for i := range g {
30 | if !visited[i] {
31 | outEdgeCount = 0
32 | g.dfs(i, visited, i, "-1")
33 | isArt[i] = outEdgeCount > 1
34 | }
35 | }
36 | return isArt
37 | }
38 |
39 | // dfsHelper recursively calls itself to solve dfs traversal
40 | func (g graph) dfs(root string, visited map[string]bool, at string, parent string) {
41 | visited[at] = true
42 | id++
43 | low[at] = id
44 | ids[at] = id
45 | for i := range g[at] {
46 | to := g[at][i]
47 | if to == parent {
48 | continue
49 | }
50 | if !visited[to] {
51 | g.dfs(root, visited, to, at)
52 | low[at] = math.Min(low[at], low[to])
53 | if ids[at] < low[to] {
54 | isArt[at] = true
55 | }
56 | if ids[at] == low[to] {
57 | isArt[at] = true
58 | }
59 | } else {
60 | low[at] = math.Min(low[at], ids[to])
61 | }
62 | }
63 | }
64 |
65 | func (g graph) simpleDisplay() {
66 | fmt.Println("")
67 | for i := range g {
68 | fmt.Print(i, " => ")
69 | for j := range g[i] {
70 | fmt.Print(g[i][j] + " ")
71 | }
72 | fmt.Println("")
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/algorithms/graphs/bellman_ford/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Node is a single node in a graph list
6 | type Node struct {
7 | name string
8 | value int
9 | }
10 |
11 | var graph map[string][]Node
12 |
13 | func init() {
14 | graph = make(map[string][]Node)
15 | }
16 |
17 | func addVertexToGraph(vtx string) {
18 | if graph[vtx] != nil {
19 | fmt.Println("\n-- Vertex already exists. --")
20 | return
21 | }
22 | vertices[vtx] = len(vertices)
23 | graph[vtx] = make([]Node, 0)
24 | }
25 |
26 | func addEdgeToGraph(fromVtx, toVtx string, edgeValue int) {
27 | if graph[fromVtx] == nil { // check if initial vertex exists
28 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
29 | return
30 | }
31 | for i := range graph[fromVtx] { // check if edge already exists
32 | if graph[fromVtx][i].name == toVtx {
33 | fmt.Println("\n-- Edge from " + fromVtx + " to " + toVtx + " already exists. --")
34 | return
35 | }
36 | }
37 | if graph[toVtx] == nil { // create new destination vertex if it does not exists
38 | vertices[toVtx] = len(vertices)
39 | graph[toVtx] = make([]Node, 0)
40 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
41 | }
42 |
43 | graph[fromVtx] = append(graph[fromVtx], Node{name: toVtx, value: edgeValue})
44 | }
45 |
46 | func addVertex() {
47 | var vtxName string
48 | fmt.Print("Enter the name of vertex: ")
49 | fmt.Scanf("%s\n", &vtxName)
50 | addVertexToGraph(vtxName)
51 | }
52 |
53 | func addEdge() {
54 | var fromVtx, toVtx string
55 | var edgeValue int
56 | fmt.Print("Enter the initial vertex name: ")
57 | fmt.Scanf("%s\n", &fromVtx)
58 | fmt.Print("Enter the destination vertex name: ")
59 | fmt.Scanf("%s\n", &toVtx)
60 | fmt.Print("Enter the weight of edge: ")
61 | fmt.Scanf("%d\n", &edgeValue)
62 | addEdgeToGraph(fromVtx, toVtx, edgeValue)
63 | }
64 |
--------------------------------------------------------------------------------
/algorithms/graphs/bridge_detection/bridge_detection.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | g := make(graph)
7 | i := 0
8 | for i == 0 {
9 | fmt.Println("\n1. ADD A VERTEX")
10 | fmt.Println("2. ADD AN EDGE")
11 | fmt.Println("3. DETECT BRIDGES")
12 | fmt.Println("4. SIMPLE DISPLAY")
13 | fmt.Println("5. EXIT")
14 | var choice int
15 | fmt.Print("Enter your choice: ")
16 | fmt.Scanf("%d\n", &choice)
17 | switch choice {
18 | case 1:
19 | g.addVertex()
20 | case 2:
21 | g.addEdge()
22 | case 3:
23 | result := g.findBridges()
24 | prev := ""
25 | if len(result) != 0 {
26 | fmt.Println("\n-- Bridge/s exists in a given graph. --")
27 | for i := range result {
28 | if prev != "" {
29 | fmt.Println("-- Bridge exists between:", prev, "-", result[i])
30 | prev = ""
31 | } else {
32 | prev = result[i]
33 | }
34 | }
35 | } else {
36 | fmt.Println("\n -- No bridge exists in a given graph. --")
37 | }
38 | case 4:
39 | g.simpleDisplay()
40 | default:
41 | fmt.Println("Command not recognized.")
42 | }
43 | }
44 | }
45 |
46 | // c-d, c-h, h-i
47 | // g.addVertexToGraph("a")
48 | // g.addVertexToGraph("b")
49 | // g.addVertexToGraph("c")
50 | // g.addVertexToGraph("d")
51 | // g.addVertexToGraph("e")
52 | // g.addVertexToGraph("f")
53 | // g.addVertexToGraph("g")
54 | // g.addVertexToGraph("h")
55 | // g.addVertexToGraph("i")
56 | // g.addEdgeToGraph("a", "b")
57 | // g.addEdgeToGraph("b", "c")
58 | // g.addEdgeToGraph("c", "a")
59 | // g.addEdgeToGraph("c", "d")
60 | // g.addEdgeToGraph("d", "e")
61 | // g.addEdgeToGraph("e", "f")
62 | // g.addEdgeToGraph("f", "g")
63 | // g.addEdgeToGraph("g", "d")
64 | // g.addEdgeToGraph("c", "h")
65 | // g.addEdgeToGraph("h", "i")
66 |
--------------------------------------------------------------------------------
/algorithms/graphs/bridge_detection/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type graph map[string][]string
6 |
7 | func (g graph) addVertexToGraph(vtx string) {
8 | if g[vtx] != nil {
9 | fmt.Println("\n-- Vertex already exists. --")
10 | return
11 | }
12 | g[vtx] = make([]string, 0)
13 | }
14 |
15 | func (g graph) addEdgeToGraph(fromVtx, toVtx string) {
16 | if g[fromVtx] == nil { // check if initial vertex exists
17 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
18 | return
19 | }
20 | for i := range g[fromVtx] { // check if edge already exists
21 | if g[fromVtx][i] == toVtx {
22 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
23 | return
24 | }
25 | }
26 | if g[toVtx] == nil { // create new destination vertext if it does not exists
27 | g[toVtx] = make([]string, 0)
28 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
29 | }
30 |
31 | g[fromVtx] = append(g[fromVtx], toVtx)
32 | g[toVtx] = append(g[toVtx], fromVtx)
33 | }
34 |
35 | func (g graph) addVertex() {
36 | var vtxName string
37 | fmt.Print("Enter the name of vertex: ")
38 | fmt.Scanf("%s\n", &vtxName)
39 | g.addVertexToGraph(vtxName)
40 | }
41 |
42 | func (g graph) addEdge() {
43 | var fromVtx, toVtx string
44 | fmt.Print("Enter the initial vertex name: ")
45 | fmt.Scanf("%s\n", &fromVtx)
46 | fmt.Print("Enter the destination vertex name: ")
47 | fmt.Scanf("%s\n", &toVtx)
48 | g.addEdgeToGraph(fromVtx, toVtx)
49 | }
50 |
--------------------------------------------------------------------------------
/algorithms/graphs/bridge_detection/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | var id float64
9 | var ids map[string]float64
10 | var low map[string]float64
11 |
12 | func init() {
13 | id = 0
14 | ids = make(map[string]float64)
15 | low = make(map[string]float64)
16 | }
17 |
18 | // DFS traverses a graph using dfs technique
19 | func (g graph) findBridges() []string {
20 | visited := make(map[string]bool)
21 | bridges := make([]string, 0)
22 | if len(g) == 0 {
23 | fmt.Println("\n-- Graph is empty. --")
24 | return nil
25 | }
26 | for i := range g {
27 | if !visited[i] {
28 | bridges = g.dfs(i, visited, "-1", bridges)
29 | }
30 | }
31 | return bridges
32 | }
33 |
34 | // dfsHelper recursively calls itself to solve dfs traversal
35 | func (g graph) dfs(at string, visited map[string]bool, parent string, bridges []string) []string {
36 | visited[at] = true
37 | id++
38 | low[at] = id
39 | ids[at] = id
40 | for i := range g[at] {
41 | to := g[at][i]
42 | if to == parent {
43 | continue
44 | }
45 | if !visited[to] {
46 | bridges = g.dfs(to, visited, at, bridges)
47 | low[at] = math.Min(low[at], low[to])
48 | if ids[at] < low[to] {
49 | bridges = append(bridges, at)
50 | bridges = append(bridges, to)
51 | }
52 | } else {
53 | low[at] = math.Min(low[at], ids[to])
54 | }
55 | }
56 | return bridges
57 | }
58 |
59 | func (g graph) simpleDisplay() {
60 | fmt.Println("")
61 | for i := range g {
62 | fmt.Print(i, " => ")
63 | for j := range g[i] {
64 | fmt.Print(g[i][j] + " ")
65 | }
66 | fmt.Println("")
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/algorithms/graphs/dijkstra/dijkstra.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // TODO: replace 999 with infinity
9 |
10 | // Dijkstra starts dijkstra algorithm on a given graph
11 | func Dijkstra(start, finish string) {
12 | var smallest string
13 | for vertex := range graph {
14 | if vertex == start {
15 | distances[vertex] = 0
16 | insertNodeInQueue(vertex, 0)
17 | } else {
18 | distances[vertex] = math.Inf(1)
19 | insertNodeInQueue(vertex, math.Inf(1))
20 | }
21 | previous[vertex] = ""
22 | }
23 |
24 | for len(pqueue) != 0 {
25 | smallest = Dequeue().name
26 | if smallest == finish {
27 | // Build path here
28 | for i := range previous {
29 | j := i
30 | fmt.Print("\nCost: ", distances[i], " units")
31 | fmt.Print(", Path: ")
32 | for j != "" {
33 | if previous[j] == "" {
34 | fmt.Print(j, "\n")
35 | } else {
36 | fmt.Print(j, " <= ")
37 | }
38 | j = previous[j]
39 | }
40 | }
41 | return
42 | }
43 | if smallest != "" || distances[smallest] != math.Inf(1) {
44 | for neighbor := range graph[smallest] {
45 | nextNode := graph[smallest][neighbor]
46 | least := distances[smallest] + nextNode.weight
47 | if least < distances[nextNode.node] {
48 | distances[nextNode.node] = least
49 | previous[nextNode.node] = smallest
50 | insertNodeInQueue(nextNode.node, least)
51 | }
52 | }
53 | }
54 | }
55 |
56 | }
57 |
58 | var graph map[string][]Node
59 | var pqueue []*QueueNode
60 | var distances map[string]float64
61 | var previous map[string]string
62 |
63 | func init() {
64 | graph = make(map[string][]Node)
65 | distances = make(map[string]float64)
66 | previous = make(map[string]string)
67 | }
68 |
69 | func main() {
70 | i := 0
71 | for i == 0 {
72 | fmt.Println("\n1. ADD A VERTEX")
73 | fmt.Println("2. ADD AN EDGE")
74 | fmt.Println("3. RUN DIJKSTRA ALGORITHM")
75 | fmt.Println("4. EXIT")
76 | var choice int
77 | fmt.Print("Enter your choice: ")
78 | fmt.Scanf("%d\n", &choice)
79 | switch choice {
80 | case 1:
81 | addVertex()
82 | case 2:
83 | addEdge()
84 | case 3:
85 | DijkstraInit()
86 | case 4:
87 | i = 1
88 | default:
89 | fmt.Println("Command not recognized.")
90 | }
91 | }
92 | }
93 |
94 | // DijkstraInit will take necessary input values from user to run
95 | // dijkstra algorithm
96 | func DijkstraInit() {
97 | var start, finish string
98 | fmt.Print("Enter the initial node: ")
99 | fmt.Scanf("%s\n", &start)
100 | fmt.Print("Enter the destination node: ")
101 | fmt.Scanf("%s\n", &finish)
102 | Dijkstra(start, finish)
103 | }
104 |
105 | func simpleDisplay() {
106 | fmt.Println("")
107 | for i := range graph {
108 | fmt.Print(i, " => ")
109 | for j := range graph[i] {
110 | fmt.Print(graph[i][j])
111 | }
112 | fmt.Println("")
113 | }
114 | }
115 |
116 | // addVertexToGraph("a")
117 | // addVertexToGraph("b")
118 | // addVertexToGraph("c")
119 | // addVertexToGraph("d")
120 | // addVertexToGraph("e")
121 | // addVertexToGraph("f")
122 | // addEdgeToGraph("a", "b", float64(4))
123 | // addEdgeToGraph("a", "c", float64(2))
124 | // addEdgeToGraph("b", "e", float64(3))
125 | // addEdgeToGraph("c", "d", float64(2))
126 | // addEdgeToGraph("c", "f", float64(4))
127 | // addEdgeToGraph("d", "e", float64(3))
128 | // addEdgeToGraph("d", "f", float64(1))
129 | // addEdgeToGraph("e", "f", float64(1))
130 | // Dijkstra("a", "e")
131 |
--------------------------------------------------------------------------------
/algorithms/graphs/dijkstra/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Node is a single node in a graph list
6 | type Node struct {
7 | node string
8 | weight float64
9 | }
10 |
11 | func addVertexToGraph(vtx string) {
12 | if graph[vtx] != nil {
13 | fmt.Println("\n-- Vertex already exists. --")
14 | return
15 | }
16 | graph[vtx] = make([]Node, 0)
17 | }
18 |
19 | func addEdgeToGraph(fromVtx, toVtx string, edgeValue float64) {
20 | if graph[fromVtx] == nil { // check if initial vertex exists
21 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
22 | return
23 | }
24 | for i := range graph[fromVtx] { // check if edge already exists
25 | if graph[fromVtx][i].node == toVtx {
26 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
27 | return
28 | }
29 | }
30 | if graph[toVtx] == nil { // create new destination vertext if it does not exists
31 | graph[toVtx] = make([]Node, 0)
32 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
33 | }
34 |
35 | graph[fromVtx] = append(graph[fromVtx], Node{node: toVtx, weight: edgeValue})
36 | graph[toVtx] = append(graph[toVtx], Node{node: fromVtx, weight: edgeValue})
37 | }
38 |
39 | func addVertex() {
40 | var vtxName string
41 | fmt.Print("Enter the name of vertex: ")
42 | fmt.Scanf("%s\n", &vtxName)
43 | addVertexToGraph(vtxName)
44 | }
45 |
46 | func addEdge() {
47 | var fromVtx, toVtx string
48 | var edgeValue int
49 | fmt.Print("Enter the initial vertex name: ")
50 | fmt.Scanf("%s\n", &fromVtx)
51 | fmt.Print("Enter the destination vertex name: ")
52 | fmt.Scanf("%s\n", &toVtx)
53 | fmt.Print("Enter the weight of edge: ")
54 | fmt.Scanf("%d\n", &edgeValue)
55 | addEdgeToGraph(fromVtx, toVtx, float64(edgeValue))
56 | }
57 |
--------------------------------------------------------------------------------
/algorithms/graphs/dijkstra/priority_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // QueueNode is a single node in a queue
9 | type QueueNode struct {
10 | name string
11 | priority float64
12 | }
13 |
14 | // Enqueue inserts a node in a heap
15 | func Enqueue(node *QueueNode) {
16 | pqueue = append(pqueue, node)
17 | minHeapify()
18 | }
19 |
20 | func minHeapify() {
21 | idx := len(pqueue) - 1
22 | element := pqueue[idx]
23 | for idx > 0 {
24 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
25 | parent := pqueue[parentIdx]
26 | if element.priority >= parent.priority {
27 | break
28 | }
29 | pqueue[parentIdx] = element
30 | pqueue[idx] = parent
31 | idx = parentIdx
32 | }
33 | }
34 |
35 | // Dequeue will remove a node from heap
36 | func Dequeue() *QueueNode {
37 | if len(pqueue) == 0 || pqueue[0] == nil {
38 | fmt.Println("\n-- Heap is empty. --")
39 | return nil
40 | }
41 | min := pqueue[0]
42 | end := pqueue[len(pqueue)-1]
43 | pqueue = pqueue[0 : len(pqueue)-1]
44 | if len(pqueue) > 0 {
45 | pqueue[0] = end
46 | bubbleDown()
47 | }
48 | return min
49 | }
50 |
51 | func bubbleDown() {
52 | idx := 0
53 | length := len(pqueue)
54 | element := pqueue[0]
55 | for {
56 | leftChildIdx := (2 * idx) + 1
57 | rightChildIdx := (2 * idx) + 2
58 | var leftChild, rightChild *QueueNode
59 | var swap int
60 |
61 | if leftChildIdx < length {
62 | leftChild = pqueue[leftChildIdx]
63 | if leftChild.priority < element.priority {
64 | swap = leftChildIdx
65 | }
66 | }
67 | if rightChildIdx < length {
68 | rightChild = pqueue[rightChildIdx]
69 | if (rightChild.priority < element.priority && swap == 0) || (rightChild.priority < leftChild.priority && swap != 0) {
70 | swap = rightChildIdx
71 | }
72 | }
73 |
74 | if swap == 0 {
75 | break
76 | }
77 | pqueue[idx] = pqueue[swap]
78 | pqueue[swap] = element
79 | idx = swap
80 | }
81 | }
82 |
83 | func insertNodeInQueue(name string, priority float64) {
84 | newNode := &QueueNode{name: name, priority: priority}
85 | Enqueue(newNode)
86 | }
87 |
88 | func display() {
89 | if len(pqueue) == 0 {
90 | fmt.Println("\n-- Heap is empty. --")
91 | return
92 | }
93 | for i := range pqueue {
94 | fmt.Println(pqueue[i].name, pqueue[i].priority)
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/algorithms/graphs/floyd_warshall/floyd_warshall.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Note: Adjacency list representation of graph was already implemented by me in previous graphs section. Hence I have
4 | // modified few things which converts this adjacency list to adjacency matrix and then the floyd warshall algorithm is
5 | // implemented. However you can directly take user inputs and add it in adjacency matrix.
6 |
7 | import (
8 | "fmt"
9 | "math"
10 | )
11 |
12 | type vertexNumber struct {
13 | value int
14 | name string
15 | }
16 |
17 | var adjacencyMatrix [][]float64
18 | var vertices map[string]int
19 |
20 | // FloydWarshall calculates all points shortest path from adjacency matrix of a graph
21 | func FloydWarshall() {
22 | for k := range adjacencyMatrix {
23 | for i := range adjacencyMatrix {
24 | for j := range adjacencyMatrix {
25 | adjacencyMatrix[i][j] = math.Min(adjacencyMatrix[i][j], adjacencyMatrix[i][k]+adjacencyMatrix[k][j])
26 | }
27 | }
28 | }
29 | fmt.Println("\n-- Final Adjacency Matrix --")
30 | for i := range adjacencyMatrix {
31 | fmt.Println(adjacencyMatrix[i])
32 | }
33 | }
34 |
35 | func init() {
36 | vertices = make(map[string]int)
37 | }
38 |
39 | func main() {
40 | fmt.Println("\n-- Floyd Warshall's Algorithm --")
41 | i := 0
42 | for i == 0 {
43 | fmt.Println("\n1. ADD A VERTEX")
44 | fmt.Println("2. ADD AN EDGE")
45 | fmt.Println("3. SIMPLE DISPLAY")
46 | fmt.Println("4. RUN FLOYD WARSHALL")
47 | fmt.Println("5. EXIT")
48 | var choice int
49 | fmt.Print("Enter your choice: ")
50 | fmt.Scanf("%d\n", &choice)
51 | switch choice {
52 | case 1:
53 | addVertex()
54 | case 2:
55 | addEdge()
56 | case 3:
57 | simpleDisplay()
58 | case 4:
59 | constructMatrix()
60 | FloydWarshall()
61 | case 5:
62 | i = 1
63 | default:
64 | fmt.Println("Command not recognized.")
65 | }
66 | }
67 | }
68 |
69 | // generates a adjacency matrix from adjacency list
70 | func constructMatrix() {
71 | count := 0
72 | adjacencyMatrix = make([][]float64, len(vertices))
73 | for i := range graph {
74 | adjacencyMatrix[vertices[i]] = make([]float64, len(vertices))
75 | for j := range graph[i] {
76 | adjacencyMatrix[vertices[i]][vertices[graph[i][j].name]] = float64(graph[i][j].value)
77 | }
78 | count++
79 | }
80 |
81 | for i := range adjacencyMatrix {
82 | for j := range adjacencyMatrix[i] {
83 | if i != j && adjacencyMatrix[i][j] == 0 {
84 | adjacencyMatrix[i][j] = math.Inf(0)
85 | }
86 | }
87 | }
88 | fmt.Println("\n-- Initial Adjacency Matrix --")
89 | for i := range adjacencyMatrix {
90 | fmt.Println(adjacencyMatrix[i])
91 | }
92 | }
93 |
94 | func simpleDisplay() {
95 | fmt.Println("")
96 | for i := range graph {
97 | fmt.Print(i, " => ")
98 | for j := range graph[i] {
99 | fmt.Print(graph[i][j])
100 | }
101 | fmt.Println("")
102 | }
103 | }
104 |
105 | // addVertexToGraph("a")
106 | // addVertexToGraph("b")
107 | // addVertexToGraph("c")
108 | // addVertexToGraph("d")
109 | // addVertexToGraph("e")
110 | // addVertexToGraph("f")
111 | // addEdgeToGraph("a", "b", 18)
112 | // addEdgeToGraph("a", "c", 20)
113 | // addEdgeToGraph("b", "d", 4)
114 | // addEdgeToGraph("c", "e", 10)
115 | // addEdgeToGraph("d", "e", 15)
116 | // addEdgeToGraph("d", "f", 23)
117 | // addEdgeToGraph("e", "f", 7)
118 | // addEdgeToGraph("d", "a", 5)
119 | // addEdgeToGraph("e", "a", 17)
120 | // addEdgeToGraph("b", "e", 21)
121 |
--------------------------------------------------------------------------------
/algorithms/graphs/floyd_warshall/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Node is a single node in a graph list
6 | type Node struct {
7 | name string
8 | value int
9 | }
10 |
11 | var graph map[string][]Node
12 |
13 | func init() {
14 | graph = make(map[string][]Node)
15 | }
16 |
17 | func addVertexToGraph(vtx string) {
18 | if graph[vtx] != nil {
19 | fmt.Println("\n-- Vertex already exists. --")
20 | return
21 | }
22 | vertices[vtx] = len(vertices)
23 | graph[vtx] = make([]Node, 0)
24 | }
25 |
26 | func addEdgeToGraph(fromVtx, toVtx string, edgeValue int) {
27 | if graph[fromVtx] == nil { // check if initial vertex exists
28 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
29 | return
30 | }
31 | for i := range graph[fromVtx] { // check if edge already exists
32 | if graph[fromVtx][i].name == toVtx {
33 | fmt.Println("\n-- Edge from " + fromVtx + " to " + toVtx + " already exists. --")
34 | return
35 | }
36 | }
37 | if graph[toVtx] == nil { // create new destination vertext if it does not exists
38 | vertices[toVtx] = len(vertices)
39 | graph[toVtx] = make([]Node, 0)
40 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
41 | }
42 |
43 | graph[fromVtx] = append(graph[fromVtx], Node{name: toVtx, value: edgeValue})
44 | }
45 |
46 | func addVertex() {
47 | var vtxName string
48 | fmt.Print("Enter the name of vertex: ")
49 | fmt.Scanf("%s\n", &vtxName)
50 | addVertexToGraph(vtxName)
51 | }
52 |
53 | func addEdge() {
54 | var fromVtx, toVtx string
55 | var edgeValue int
56 | fmt.Print("Enter the initial vertex name: ")
57 | fmt.Scanf("%s\n", &fromVtx)
58 | fmt.Print("Enter the destination vertex name: ")
59 | fmt.Scanf("%s\n", &toVtx)
60 | fmt.Print("Enter the weight of edge: ")
61 | fmt.Scanf("%d\n", &edgeValue)
62 | addEdgeToGraph(fromVtx, toVtx, edgeValue)
63 | }
64 |
--------------------------------------------------------------------------------
/algorithms/graphs/kruskals/heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // HeapNode is a single node in a queue
9 | type HeapNode struct {
10 | name string
11 | priority float64
12 | }
13 |
14 | // Enqueue inserts a node in a heap
15 | func Enqueue(node *HeapNode) {
16 | heap = append(heap, node)
17 | hashMap[node.name] = len(heap) - 1
18 | minHeapify(-1)
19 | }
20 |
21 | func minHeapify(idx int) {
22 | if idx == -1 {
23 | idx = len(heap) - 1
24 | }
25 | element := heap[idx]
26 | for idx > 0 {
27 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
28 | parent := heap[parentIdx]
29 | if element.priority >= parent.priority {
30 | break
31 | }
32 | heap[parentIdx] = element
33 | hashMap[element.name] = parentIdx
34 | heap[idx] = parent
35 | hashMap[parent.name] = idx
36 | idx = parentIdx
37 | }
38 | }
39 |
40 | // Dequeue will remove a node from heap
41 | func Dequeue() *HeapNode {
42 | if len(heap) == 0 || heap[0] == nil {
43 | fmt.Println("\n-- Heap is empty. --")
44 | return nil
45 | }
46 | min := heap[0]
47 | end := heap[len(heap)-1]
48 | heap = heap[0 : len(heap)-1]
49 | hashMap[end.name] = 0
50 | if len(heap) > 0 {
51 | heap[0] = end
52 | bubbleDown()
53 | }
54 | delete(hashMap, min.name)
55 | return min
56 | }
57 |
58 | func bubbleDown() {
59 | idx := 0
60 | length := len(heap)
61 | element := heap[0]
62 | for {
63 | leftChildIdx := (2 * idx) + 1
64 | rightChildIdx := (2 * idx) + 2
65 | var leftChild, rightChild *HeapNode
66 | var swap int
67 |
68 | if leftChildIdx < length {
69 | leftChild = heap[leftChildIdx]
70 | if leftChild.priority < element.priority {
71 | swap = leftChildIdx
72 | }
73 | }
74 | if rightChildIdx < length {
75 | rightChild = heap[rightChildIdx]
76 | if (rightChild.priority < element.priority && swap == 0) || (rightChild.priority < leftChild.priority && swap != 0) {
77 | swap = rightChildIdx
78 | }
79 | }
80 |
81 | if swap == 0 {
82 | break
83 | }
84 | heap[idx] = heap[swap]
85 | hashMap[heap[swap].name] = idx
86 | heap[swap] = element
87 | hashMap[element.name] = swap
88 | idx = swap
89 | }
90 | }
91 |
92 | // DecreaseKey will decrease the priority of a given node positioned by index in a heap
93 | // will then call minHeapify to satisfy the min heap property
94 | func DecreaseKey(index int, newValue float64) {
95 | heap[index].priority = newValue
96 | minHeapify(index)
97 | }
98 |
99 | var heap []*HeapNode
100 |
101 | // hasMap maps heap values to heap indexes
102 | var hashMap map[string]int
103 |
104 | func init() {
105 | hashMap = make(map[string]int)
106 | }
107 |
108 | func insertNode(name string, priority float64) {
109 | newNode := &HeapNode{name: name, priority: priority}
110 | Enqueue(newNode)
111 | }
112 |
--------------------------------------------------------------------------------
/algorithms/graphs/kruskals/kruskals.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Kruskals will run kruskal's algorithm on a given graph
6 | func (g graph) Kruskals(start string) {
7 | count := 0
8 | mst := make(graph)
9 | for count != len(g)-1 {
10 | node := Dequeue()
11 | mst.addVertexToGraph(string(node.name[0]))
12 | mst.addVertexToGraph(string(node.name[1]))
13 | mst.addEdgeToGraph(string(node.name[0]), string(node.name[1]), node.priority)
14 | isCyclic := mst.DFS(string(node.name[0]))
15 | if isCyclic {
16 | mst.removeEdgeFromGraph(string(node.name[0]), string(node.name[1]))
17 | count--
18 | }
19 | count++
20 | }
21 | mst.printKruskals(start)
22 | }
23 |
24 | var uniqueEdges []Edge
25 |
26 | func init() {
27 | uniqueEdges = make([]Edge, 0)
28 | }
29 |
30 | func main() {
31 | g := make(graph)
32 | i := 0
33 | for i == 0 {
34 | fmt.Println("\n1. ADD A VERTEX")
35 | fmt.Println("2. ADD AN EDGE")
36 | fmt.Println("3. RUN PRIM's ALGORITHM")
37 | fmt.Println("4. SIMPLE DISPLAY")
38 | fmt.Println("5. EXIT")
39 | var choice int
40 | fmt.Print("Enter your choice: ")
41 | fmt.Scanf("%d\n", &choice)
42 | switch choice {
43 | case 1:
44 | g.addVertex()
45 | case 2:
46 | g.addEdge()
47 | case 3:
48 | g.startKruskals()
49 | case 4:
50 | g.simpleDisplay()
51 | case 5:
52 | i = 1
53 | default:
54 | fmt.Println("Command not recognized.")
55 | }
56 | }
57 | }
58 |
59 | func (g graph) startKruskals() {
60 | var start string
61 | fmt.Print("Enter the source vertex: ")
62 | fmt.Scanf("%s\n", &start)
63 | for _, edge := range uniqueEdges {
64 | insertNode(edge.src+edge.dest, edge.value)
65 | }
66 | g.Kruskals(start)
67 | }
68 |
69 | func (g graph) printKruskals(start string) {
70 | visited := make(map[string]bool)
71 | for i := range g {
72 | for _, node := range g[i] {
73 | if !visited[node.name+i] {
74 | fmt.Println(i, "-", node.name, "=>", node.value)
75 | }
76 | visited[node.name+i] = true
77 | visited[i+node.name] = true
78 | }
79 | }
80 | }
81 |
82 | // g.addVertexToGraph("0")
83 | // g.addVertexToGraph("1")
84 | // g.addVertexToGraph("2")
85 | // g.addVertexToGraph("3")
86 | // g.addVertexToGraph("4")
87 | // g.addVertexToGraph("5")
88 | // g.addVertexToGraph("6")
89 | // g.addVertexToGraph("7")
90 | // g.addVertexToGraph("8")
91 | // g.addEdgeToGraph("0", "1", 4)
92 | // g.addEdgeToGraph("0", "7", 8)
93 | // g.addEdgeToGraph("1", "2", 8)
94 | // g.addEdgeToGraph("1", "7", 11)
95 | // g.addEdgeToGraph("2", "3", 7)
96 | // g.addEdgeToGraph("2", "5", 4)
97 | // g.addEdgeToGraph("2", "8", 2)
98 | // g.addEdgeToGraph("3", "4", 9)
99 | // g.addEdgeToGraph("3", "5", 14)
100 | // g.addEdgeToGraph("4", "5", 10)
101 | // g.addEdgeToGraph("5", "6", 2)
102 | // g.addEdgeToGraph("6", "8", 6)
103 | // g.addEdgeToGraph("6", "7", 1)
104 | // g.addEdgeToGraph("7", "8", 7)
105 | // g.startKruskals()
106 |
--------------------------------------------------------------------------------
/algorithms/graphs/prims/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // GraphNode is a node in a graph list
6 | type GraphNode struct {
7 | name string
8 | value float64
9 | }
10 |
11 | // graph is a data structure which will be holding a graph
12 | type graph map[string][]GraphNode
13 |
14 | // addVertexToGraph adds a vertex to graph
15 | func (g graph) addVertexToGraph(vtx string) {
16 | if g[vtx] != nil {
17 | fmt.Println("\n-- Vertex already exists. --")
18 | return
19 | }
20 | g[vtx] = make([]GraphNode, 0)
21 | }
22 |
23 | // addEdgeToGraph adds an edge to a graph
24 | func (g graph) addEdgeToGraph(fromVtx, toVtx string, edgeValue float64) {
25 | if g[fromVtx] == nil { // check if initial vertex exists
26 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
27 | return
28 | }
29 | for i := range g[fromVtx] { // check if edge already exists
30 | if g[fromVtx][i].name == toVtx {
31 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
32 | return
33 | }
34 | }
35 | if g[toVtx] == nil { // create new destination vertext if it does not exists
36 | g[toVtx] = make([]GraphNode, 0)
37 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
38 | }
39 |
40 | g[fromVtx] = append(g[fromVtx], GraphNode{name: toVtx, value: edgeValue})
41 | g[toVtx] = append(g[toVtx], GraphNode{name: fromVtx, value: edgeValue})
42 | }
43 |
44 | // addVertex asks user to enter vertex name
45 | func (g graph) addVertex() {
46 | var vtxName string
47 | fmt.Print("Enter the name of vertex: ")
48 | fmt.Scanf("%s\n", &vtxName)
49 | g.addVertexToGraph(vtxName)
50 | }
51 |
52 | // addEdge asks user to enter necessary values before adding an edge to graph
53 | func (g graph) addEdge() {
54 | var fromVtx, toVtx string
55 | var edgeValue float64
56 | fmt.Print("Enter the initial vertex name: ")
57 | fmt.Scanf("%s\n", &fromVtx)
58 | fmt.Print("Enter the destination vertex name: ")
59 | fmt.Scanf("%s\n", &toVtx)
60 | fmt.Print("Enter the weight of edge: ")
61 | fmt.Scanf("%d\n", &edgeValue)
62 | g.addEdgeToGraph(fromVtx, toVtx, edgeValue)
63 | }
64 |
65 | // simpleDisplay simply displays a graph
66 | func (g graph) simpleDisplay() {
67 | fmt.Println("")
68 | for i := range g {
69 | fmt.Print(i, " => ")
70 | for j := range g[i] {
71 | fmt.Print(g[i][j])
72 | }
73 | fmt.Println("")
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/algorithms/graphs/prims/heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // HeapNode is a single node in a queue
9 | type HeapNode struct {
10 | name string
11 | priority float64
12 | }
13 |
14 | // Enqueue inserts a node in a heap
15 | func Enqueue(node *HeapNode) {
16 | heap = append(heap, node)
17 | hashMap[node.name] = len(heap) - 1
18 | minHeapify(-1)
19 | }
20 |
21 | func minHeapify(idx int) {
22 | if idx == -1 {
23 | idx = len(heap) - 1
24 | }
25 | element := heap[idx]
26 | for idx > 0 {
27 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
28 | parent := heap[parentIdx]
29 | if element.priority >= parent.priority {
30 | break
31 | }
32 | heap[parentIdx] = element
33 | hashMap[element.name] = parentIdx
34 | heap[idx] = parent
35 | hashMap[parent.name] = idx
36 | idx = parentIdx
37 | }
38 | }
39 |
40 | // Dequeue will remove a node from heap
41 | func Dequeue() *HeapNode {
42 | if len(heap) == 0 || heap[0] == nil {
43 | fmt.Println("\n-- Heap is empty. --")
44 | return nil
45 | }
46 | min := heap[0]
47 | end := heap[len(heap)-1]
48 | heap = heap[0 : len(heap)-1]
49 | hashMap[end.name] = 0
50 | if len(heap) > 0 {
51 | heap[0] = end
52 | bubbleDown()
53 | }
54 | delete(hashMap, min.name)
55 | return min
56 | }
57 |
58 | func bubbleDown() {
59 | idx := 0
60 | length := len(heap)
61 | element := heap[0]
62 | for {
63 | leftChildIdx := (2 * idx) + 1
64 | rightChildIdx := (2 * idx) + 2
65 | var leftChild, rightChild *HeapNode
66 | var swap int
67 |
68 | if leftChildIdx < length {
69 | leftChild = heap[leftChildIdx]
70 | if leftChild.priority < element.priority {
71 | swap = leftChildIdx
72 | }
73 | }
74 | if rightChildIdx < length {
75 | rightChild = heap[rightChildIdx]
76 | if (rightChild.priority < element.priority && swap == 0) || (rightChild.priority < leftChild.priority && swap != 0) {
77 | swap = rightChildIdx
78 | }
79 | }
80 |
81 | if swap == 0 {
82 | break
83 | }
84 | heap[idx] = heap[swap]
85 | hashMap[heap[swap].name] = idx
86 | heap[swap] = element
87 | hashMap[element.name] = swap
88 | idx = swap
89 | }
90 | }
91 |
92 | // DecreaseKey will decrease the priority of a given node positioned by index in a heap
93 | // will then call minHeapify to satisfy the min heap property
94 | func DecreaseKey(index int, newValue float64) {
95 | heap[index].priority = newValue
96 | minHeapify(index)
97 | }
98 |
99 | var heap []*HeapNode
100 |
101 | // hasMap maps heap values to heap indexes
102 | var hashMap map[string]int
103 |
104 | func init() {
105 | hashMap = make(map[string]int)
106 | }
107 |
108 | func insertNode(name string, priority float64) {
109 | newNode := &HeapNode{name: name, priority: priority}
110 | Enqueue(newNode)
111 | }
112 |
--------------------------------------------------------------------------------
/algorithms/graphs/topological_sort/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type graph map[string][]string
6 |
7 | func (g graph) addVertexToGraph(vtx string) {
8 | if g[vtx] != nil {
9 | fmt.Println("\n-- Vertex already exists. --")
10 | return
11 | }
12 | g[vtx] = make([]string, 0)
13 | }
14 |
15 | func (g graph) addEdgeToGraph(fromVtx, toVtx string) {
16 | if g[fromVtx] == nil { // check if initial vertex exists
17 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
18 | return
19 | }
20 | for i := range g[fromVtx] { // check if edge already exists
21 | if g[fromVtx][i] == toVtx {
22 | fmt.Println("\n-- Edge from " + fromVtx + " to " + toVtx + " already exists. --")
23 | return
24 | }
25 | }
26 | if g[toVtx] == nil { // create new destination vertext if it does not exists
27 | g[toVtx] = make([]string, 0)
28 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
29 | }
30 |
31 | g[fromVtx] = append(g[fromVtx], toVtx)
32 | }
33 |
34 | // detectDFS traverses a graph using dfs technique to detect a cycle in a graph
35 | func (g graph) detectDFS() ([]string, bool) {
36 | visited := make(map[string]bool)
37 | stack := make(map[string]string) // keeps track of stack
38 | var cycle bool
39 | var result []string
40 | var finalResult []string
41 | if len(g) == 0 {
42 | fmt.Println("\n-- Graph is empty. --")
43 | return nil, false
44 | }
45 | for i := range g {
46 | if !visited[i] {
47 | stack[i] = i
48 | result, cycle = g.dfsHelper(i, visited, result, stack)
49 |
50 | // appending the result into finalResult in reverse order making topological sort
51 | for i := len(result) - 1; i >= 0; i-- {
52 | finalResult = append(finalResult, result[i])
53 | }
54 | result = make([]string, 0)
55 |
56 | delete(stack, i)
57 | if cycle {
58 | return nil, cycle
59 | }
60 | }
61 | }
62 | return finalResult, cycle
63 | }
64 |
65 | // dfsHelper recursively calls itself to solve dfs traversal
66 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string, stack map[string]string) ([]string, bool) {
67 | visited[vtx] = true
68 | cycle := false
69 | result = append(result, vtx)
70 | for i := range g[vtx] {
71 | if stack[g[vtx][i]] == g[vtx][i] { // cycle detection logic is here
72 | return nil, true
73 | }
74 | if !visited[g[vtx][i]] {
75 | stack[g[vtx][i]] = g[vtx][i]
76 | result, cycle = g.dfsHelper(g[vtx][i], visited, result, stack)
77 | delete(stack, g[vtx][i])
78 | return result, cycle
79 | }
80 | }
81 | return result, cycle
82 | }
83 |
84 | func (g graph) addVertex() {
85 | var vtxName string
86 | fmt.Print("Enter the name of vertex: ")
87 | fmt.Scanf("%s\n", &vtxName)
88 | g.addVertexToGraph(vtxName)
89 | }
90 |
91 | func (g graph) addEdge() {
92 | var fromVtx, toVtx string
93 | fmt.Print("Enter the initial vertex name: ")
94 | fmt.Scanf("%s\n", &fromVtx)
95 | fmt.Print("Enter the destination vertex name: ")
96 | fmt.Scanf("%s\n", &toVtx)
97 | g.addEdgeToGraph(fromVtx, toVtx)
98 | }
99 |
--------------------------------------------------------------------------------
/algorithms/graphs/topological_sort/topological_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | g := make(graph)
7 | i := 0
8 | for i == 0 {
9 | fmt.Println("\n1. ADD A VERTEX")
10 | fmt.Println("2. ADD AN EDGE")
11 | fmt.Println("3. RUN TOPOLOGICAL SORT")
12 | fmt.Println("4. EXIT")
13 | var choice int
14 | fmt.Print("Enter your choice: ")
15 | fmt.Scanf("%d\n", &choice)
16 | switch choice {
17 | case 1:
18 | g.addVertex()
19 | case 2:
20 | g.addEdge()
21 | case 3:
22 | g.runTopological()
23 | case 4:
24 | i = 1
25 | default:
26 | fmt.Println("Command not recognized.")
27 | }
28 | }
29 | }
30 |
31 | func (g graph) runTopological() {
32 | result, cycle := g.detectDFS()
33 | if cycle {
34 | fmt.Println("\n-- Can't run Topological Sort. The graph is cyclic. --")
35 | } else {
36 | fmt.Println("\nSuccessfully ran Topological Sort:")
37 | for i := range result {
38 | fmt.Print(" ", result[i])
39 | }
40 | fmt.Println("")
41 | }
42 | }
43 |
44 | // cyclic
45 | // g.addVertexToGraph("0")
46 | // g.addVertexToGraph("1")
47 | // g.addVertexToGraph("2")
48 | // g.addVertexToGraph("3")
49 | // g.addVertexToGraph("4")
50 | // g.addEdgeToGraph("0", "1")
51 | // g.addEdgeToGraph("1", "2")
52 | // g.addEdgeToGraph("2", "4")
53 | // g.addEdgeToGraph("2", "3")
54 | // g.addEdgeToGraph("3", "0")
55 | // g.addEdgeToGraph("4", "2")
56 |
57 | // acyclic
58 | // g.addVertexToGraph("0")
59 | // g.addVertexToGraph("1")
60 | // g.addVertexToGraph("2")
61 | // g.addVertexToGraph("3")
62 | // g.addVertexToGraph("4")
63 | // g.addEdgeToGraph("0", "1")
64 | // g.addEdgeToGraph("1", "2")
65 | // g.addEdgeToGraph("2", "3")
66 | // g.addEdgeToGraph("4", "2")
67 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_directed_graph_traversals/cycle_detection.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | g := make(graph)
7 | i := 0
8 | for i == 0 {
9 | fmt.Println("\n1. ADD A VERTEX")
10 | fmt.Println("2. ADD AN EDGE")
11 | fmt.Println("3. DETECT CYCLE USING DFS")
12 | fmt.Println("4. DETECT CYCLE USING BFS")
13 | fmt.Println("5. SIMPLE DISPLAY")
14 | fmt.Println("6. EXIT")
15 | var choice int
16 | fmt.Print("Enter your choice: ")
17 | fmt.Scanf("%d\n", &choice)
18 | switch choice {
19 | case 1:
20 | g.addVertex()
21 | case 2:
22 | g.addEdge()
23 | case 3:
24 | _, cycle := g.detectDFS()
25 | if cycle {
26 | fmt.Println("\n-- Given graph is cyclic. --")
27 | } else {
28 | fmt.Println("\n-- Given graph is acyclic. --")
29 | }
30 | case 4:
31 | result := g.detectBFS()
32 | fmt.Println(result)
33 | case 5:
34 | g.simpleDisplay()
35 | case 6:
36 | i = 1
37 | default:
38 | fmt.Println("Command not recognized.")
39 | }
40 | }
41 | }
42 |
43 | // cyclic
44 | // g.addVertexToGraph("0")
45 | // g.addVertexToGraph("1")
46 | // g.addVertexToGraph("2")
47 | // g.addVertexToGraph("3")
48 | // g.addVertexToGraph("4")
49 | // g.addEdgeToGraph("0", "1")
50 | // g.addEdgeToGraph("1", "2")
51 | // g.addEdgeToGraph("2", "4")
52 | // g.addEdgeToGraph("2", "3")
53 | // g.addEdgeToGraph("3", "0")
54 | // g.addEdgeToGraph("4", "2")
55 |
56 | // acyclic
57 | // g.addVertexToGraph("0")
58 | // g.addVertexToGraph("1")
59 | // g.addVertexToGraph("2")
60 | // g.addVertexToGraph("3")
61 | // g.addVertexToGraph("4")
62 | // g.addEdgeToGraph("0", "1")
63 | // g.addEdgeToGraph("1", "2")
64 | // g.addEdgeToGraph("2", "3")
65 | // g.addEdgeToGraph("4", "2")
66 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_directed_graph_traversals/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type graph map[string][]string
6 |
7 | func (g graph) addVertexToGraph(vtx string) {
8 | if g[vtx] != nil {
9 | fmt.Println("\n-- Vertex already exists. --")
10 | return
11 | }
12 | g[vtx] = make([]string, 0)
13 | }
14 |
15 | func (g graph) addEdgeToGraph(fromVtx, toVtx string) {
16 | if g[fromVtx] == nil { // check if initial vertex exists
17 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
18 | return
19 | }
20 | for i := range g[fromVtx] { // check if edge already exists
21 | if g[fromVtx][i] == toVtx {
22 | fmt.Println("\n-- Edge from " + fromVtx + " to " + toVtx + " already exists. --")
23 | return
24 | }
25 | }
26 | if g[toVtx] == nil { // create new destination vertext if it does not exists
27 | g[toVtx] = make([]string, 0)
28 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
29 | }
30 |
31 | g[fromVtx] = append(g[fromVtx], toVtx)
32 | }
33 |
34 | func (g graph) addVertex() {
35 | var vtxName string
36 | fmt.Print("Enter the name of vertex: ")
37 | fmt.Scanf("%s\n", &vtxName)
38 | g.addVertexToGraph(vtxName)
39 | }
40 |
41 | func (g graph) addEdge() {
42 | var fromVtx, toVtx string
43 | fmt.Print("Enter the initial vertex name: ")
44 | fmt.Scanf("%s\n", &fromVtx)
45 | fmt.Print("Enter the destination vertex name: ")
46 | fmt.Scanf("%s\n", &toVtx)
47 | g.addEdgeToGraph(fromVtx, toVtx)
48 | }
49 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_directed_graph_traversals/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // detectDFS traverses a graph using dfs technique to detect a cycle in a graph
6 | func (g graph) detectDFS() ([]string, bool) {
7 | visited := make(map[string]bool)
8 | stack := make(map[string]string) // keeps track of stack
9 | var cycle bool
10 | var result []string
11 | if len(g) == 0 {
12 | fmt.Println("\n-- Graph is empty. --")
13 | return nil, false
14 | }
15 | for i := range g {
16 | if !visited[i] {
17 | stack[i] = i
18 | result, cycle = g.dfsHelper(i, visited, result, stack)
19 | delete(stack, i)
20 | if cycle {
21 | return nil, cycle
22 | }
23 | }
24 | }
25 | return result, cycle
26 | }
27 |
28 | // dfsHelper recursively calls itself to solve dfs traversal
29 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string, stack map[string]string) ([]string, bool) {
30 | visited[vtx] = true
31 | cycle := false
32 | result = append(result, vtx)
33 | for i := range g[vtx] {
34 | if stack[g[vtx][i]] == g[vtx][i] { // cycle detection logic is here
35 | return nil, true
36 | }
37 | if !visited[g[vtx][i]] {
38 | stack[g[vtx][i]] = g[vtx][i]
39 | result, cycle = g.dfsHelper(g[vtx][i], visited, result, stack)
40 | delete(stack, g[vtx][i])
41 | return result, cycle
42 | }
43 | }
44 | return result, cycle
45 | }
46 |
47 | // TODO:
48 | // detectBFS traverses a graph using dfs technique to detect cycle using BFS
49 | func (g graph) detectBFS() []string {
50 |
51 | if len(g) == 0 {
52 | fmt.Println("\n-- Graph is empty. --")
53 | return nil
54 | }
55 |
56 | visited := make(map[string]bool)
57 |
58 | var queue []string
59 | var result []string
60 | var currentVtx string
61 |
62 | for i := range g {
63 | if !visited[i] {
64 | visited[i] = true
65 | queue = append(queue, i)
66 |
67 | for len(queue) != 0 {
68 | currentVtx = queue[0] // get the element from the queue
69 | queue = queue[1:] // remove element from the queue
70 | result = append(result, currentVtx) // push the current vertex in result
71 |
72 | for j := range g[currentVtx] {
73 | if !visited[g[currentVtx][j]] {
74 | visited[g[currentVtx][j]] = true // mark as visited
75 | queue = append(queue, g[currentVtx][j]) // push neighbors of current vertex in the queue
76 | }
77 | }
78 |
79 | }
80 |
81 | }
82 | }
83 |
84 | return result
85 | }
86 |
87 | func (g graph) simpleDisplay() {
88 | fmt.Println("")
89 | for i := range g {
90 | fmt.Print(i, " => ")
91 | for j := range g[i] {
92 | fmt.Print(g[i][j] + " ")
93 | }
94 | fmt.Println("")
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_undirected_graph_traversals/cycle_detection.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | g := make(graph)
7 |
8 | i := 0
9 | for i == 0 {
10 | fmt.Println("\n1. ADD A VERTEX")
11 | fmt.Println("2. ADD AN EDGE")
12 | fmt.Println("3. DETECT CYCLE USING DFS")
13 | fmt.Println("4. DETECT CYCLE USING BFS")
14 | fmt.Println("5. SIMPLE DISPLAY")
15 | fmt.Println("6. EXIT")
16 | var choice int
17 | fmt.Print("Enter your choice: ")
18 | fmt.Scanf("%d\n", &choice)
19 | switch choice {
20 | case 1:
21 | g.addVertex()
22 | case 2:
23 | g.addEdge()
24 | case 3:
25 | result, cycle := g.detectDFS()
26 | if cycle {
27 | fmt.Println("\n-- Given graph is cyclic. --")
28 | } else if result != nil && !cycle {
29 | fmt.Println("\n-- Given graph is acyclic. --")
30 | }
31 | case 4:
32 | result := g.detectBFS()
33 | fmt.Println(result)
34 | case 5:
35 | g.simpleDisplay()
36 | case 6:
37 | i = 1
38 | default:
39 | fmt.Println("Command not recognized.")
40 | }
41 | }
42 | }
43 |
44 | func (g graph) simpleDisplay() {
45 | fmt.Println("")
46 | for i := range g {
47 | fmt.Print(i, " => ")
48 | for j := range g[i] {
49 | fmt.Print(g[i][j] + " ")
50 | }
51 | fmt.Println("")
52 | }
53 | }
54 |
55 | // cyclic
56 | // g.addVertexToGraph("0")
57 | // g.addVertexToGraph("1")
58 | // g.addVertexToGraph("2")
59 | // g.addVertexToGraph("3")
60 | // g.addVertexToGraph("4")
61 | // g.addEdgeToGraph("0", "1")
62 | // g.addEdgeToGraph("1", "2")
63 | // g.addEdgeToGraph("2", "4")
64 | // g.addEdgeToGraph("2", "3")
65 | // g.addEdgeToGraph("3", "0")
66 | // g.addEdgeToGraph("4", "2")
67 |
68 | // acyclic
69 | // g.addVertexToGraph("0")
70 | // g.addVertexToGraph("1")
71 | // g.addVertexToGraph("2")
72 | // g.addVertexToGraph("3")
73 | // g.addVertexToGraph("4")
74 | // g.addEdgeToGraph("0", "1")
75 | // g.addEdgeToGraph("1", "2")
76 | // g.addEdgeToGraph("2", "3")
77 | // g.addEdgeToGraph("4", "2")
78 |
79 | // cyclic
80 | // g.addVertexToGraph("0")
81 | // g.addVertexToGraph("1")
82 | // g.addVertexToGraph("2")
83 | // g.addVertexToGraph("3")
84 | // g.addVertexToGraph("4")
85 | // g.addEdgeToGraph("0", "1")
86 | // g.addEdgeToGraph("0", "2")
87 | // g.addEdgeToGraph("2", "3")
88 | // g.addEdgeToGraph("2", "4")
89 | // g.addEdgeToGraph("3", "4")
90 |
91 | // acyclic
92 | // g.addVertexToGraph("0")
93 | // g.addVertexToGraph("1")
94 | // g.addVertexToGraph("2")
95 | // g.addVertexToGraph("3")
96 | // g.addVertexToGraph("4")
97 | // g.addEdgeToGraph("0", "1")
98 | // g.addEdgeToGraph("0", "2")
99 | // g.addEdgeToGraph("2", "3")
100 | // g.addEdgeToGraph("2", "4")
101 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_undirected_graph_traversals/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type graph map[string][]string
6 |
7 | func (g graph) addVertexToGraph(vtx string) {
8 | if g[vtx] != nil {
9 | fmt.Println("\n-- Vertex already exists. --")
10 | return
11 | }
12 | g[vtx] = make([]string, 0)
13 | }
14 |
15 | func (g graph) addEdgeToGraph(fromVtx, toVtx string) {
16 | if g[fromVtx] == nil { // check if initial vertex exists
17 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
18 | return
19 | }
20 | for i := range g[fromVtx] { // check if edge already exists
21 | if g[fromVtx][i] == toVtx {
22 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
23 | return
24 | }
25 | }
26 | if g[toVtx] == nil { // create new destination vertext if it does not exists
27 | g[toVtx] = make([]string, 0)
28 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
29 | }
30 |
31 | g[fromVtx] = append(g[fromVtx], toVtx)
32 | g[toVtx] = append(g[toVtx], fromVtx)
33 | }
34 |
35 | func (g graph) addVertex() {
36 | var vtxName string
37 | fmt.Print("Enter the name of vertex: ")
38 | fmt.Scanf("%s\n", &vtxName)
39 | g.addVertexToGraph(vtxName)
40 | }
41 |
42 | func (g graph) addEdge() {
43 | var fromVtx, toVtx string
44 | fmt.Print("Enter the initial vertex name: ")
45 | fmt.Scanf("%s\n", &fromVtx)
46 | fmt.Print("Enter the destination vertex name: ")
47 | fmt.Scanf("%s\n", &toVtx)
48 | g.addEdgeToGraph(fromVtx, toVtx)
49 | }
50 |
--------------------------------------------------------------------------------
/algorithms/graphs/traversals/cd_undirected_graph_traversals/traversals.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // detectDFS traverses a graph using dfs technique to detect cycle in a graph
6 | func (g graph) detectDFS() ([]string, bool) {
7 | visited := make(map[string]bool)
8 | cycle := false
9 | var result []string
10 | if len(g) == 0 {
11 | fmt.Println("\n-- Graph is empty. --")
12 | return nil, false
13 | }
14 | for i := range g {
15 | if !visited[i] {
16 | result, cycle = g.dfsHelper(i, visited, result, "-1")
17 | if cycle {
18 | return nil, cycle
19 | }
20 | }
21 | }
22 | return result, cycle
23 | }
24 |
25 | // dfsHelper recursively calls itself to solve dfs traversal
26 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string, parent string) ([]string, bool) {
27 | visited[vtx] = true
28 | cycle := false
29 | result = append(result, vtx)
30 | for i := range g[vtx] {
31 | fmt.Println(parent, vtx, g[vtx][i])
32 | if parent != g[vtx][i] && parent != "-1" && visited[g[vtx][i]] { // cycle detection logic here
33 | return nil, true
34 | }
35 | if !visited[g[vtx][i]] {
36 | result, cycle = g.dfsHelper(g[vtx][i], visited, result, vtx)
37 | return result, cycle
38 | }
39 | }
40 | return result, cycle
41 | }
42 |
43 | // TODO:
44 | // detectBFS traverses a graph using dfs technique to detect cycle in a graph
45 | func (g graph) detectBFS() []string {
46 |
47 | if len(g) == 0 {
48 | fmt.Println("\n-- Graph is empty. --")
49 | return nil
50 | }
51 |
52 | visited := make(map[string]bool)
53 |
54 | var queue []string
55 | var result []string
56 | var currentVtx string
57 |
58 | for i := range g {
59 | if !visited[i] {
60 | visited[i] = true
61 | queue = append(queue, i)
62 |
63 | for len(queue) != 0 {
64 | currentVtx = queue[0] // get the element from the queue
65 | queue = queue[1:] // remove element from the queue
66 | result = append(result, currentVtx) // push the current vertex in result
67 |
68 | for i := range g[currentVtx] {
69 | if !visited[g[currentVtx][i]] {
70 | visited[g[currentVtx][i]] = true // mark as visited
71 | queue = append(queue, g[currentVtx][i]) // push neighbors of current vertex in the queue
72 | }
73 | }
74 |
75 | }
76 |
77 | }
78 | }
79 |
80 | return result
81 | }
82 |
--------------------------------------------------------------------------------
/algorithms/graphs/tsp/tsp_dynamic/directed_graph/helpers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "math"
5 | )
6 |
7 | func notIn(elem, subset uint32) bool {
8 | return ((1 << elem) & subset) == 0
9 | }
10 |
11 | func combinations(set, at, r, n uint32, subsets *[]uint32) *[]uint32 {
12 | elementsLeftToPick := n - at
13 | if elementsLeftToPick < r {
14 | return subsets
15 | }
16 |
17 | if r == 0 {
18 | *subsets = append(*subsets, set)
19 | } else {
20 | for i := at; i < n; i++ {
21 | set ^= (1 << i)
22 | combinations(set, i+1, r-1, n, subsets)
23 | set ^= (1 << i)
24 | }
25 | }
26 | return subsets
27 | }
28 |
29 | func constructMatrix(g graph) {
30 | numToVtx = make(map[int]string)
31 | vtxToNum = make(map[string]int)
32 | num := 0
33 | for i := range g {
34 | numToVtx[num] = i
35 | vtxToNum[i] = num
36 | num++
37 | }
38 |
39 | distanceMatrix = make([][]float64, len(numToVtx))
40 |
41 | for i := range g {
42 | distanceMatrix[vtxToNum[i]] = make([]float64, len(vtxToNum))
43 | for j := range distanceMatrix[vtxToNum[i]] {
44 | distanceMatrix[vtxToNum[i]][j] = math.Inf(1)
45 | }
46 | for j := range g[i] {
47 | distanceMatrix[vtxToNum[i]][vtxToNum[g[i][j].name]] = float64(g[i][j].value)
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/algorithms/graphs/tsp/tsp_dynamic/undirected_graph/helpers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "math"
5 | )
6 |
7 | func notIn(elem, subset uint32) bool {
8 | return ((1 << elem) & subset) == 0
9 | }
10 |
11 | func combinations(set, at, r, n uint32, subsets *[]uint32) *[]uint32 {
12 | elementsLeftToPick := n - at
13 | if elementsLeftToPick < r {
14 | return subsets
15 | }
16 |
17 | if r == 0 {
18 | *subsets = append(*subsets, set)
19 | } else {
20 | for i := at; i < n; i++ {
21 | set ^= (1 << i)
22 | combinations(set, i+1, r-1, n, subsets)
23 | set ^= (1 << i)
24 | }
25 | }
26 | return subsets
27 | }
28 |
29 | func constructMatrix(g graph) {
30 | numToVtx = make(map[int]string)
31 | vtxToNum = make(map[string]int)
32 | num := 0
33 | for i := range g {
34 | numToVtx[num] = i
35 | vtxToNum[i] = num
36 | num++
37 | }
38 |
39 | distanceMatrix = make([][]float64, len(numToVtx))
40 |
41 | for i := range g {
42 | distanceMatrix[vtxToNum[i]] = make([]float64, len(vtxToNum))
43 | for j := range distanceMatrix[vtxToNum[i]] {
44 | distanceMatrix[vtxToNum[i]][j] = math.Inf(1)
45 | }
46 | for j := range g[i] {
47 | distanceMatrix[vtxToNum[i]][vtxToNum[g[i][j].name]] = float64(g[i][j].value)
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/algorithms/graphs/tsp/tsp_naive/directed_graph/lo_permutations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strings"
5 | )
6 |
7 | // LOP performs Lexicographic Order Permutations on a given string.
8 | // Returns all possibilities as a slice of string.
9 | func LOP(str []string) []string {
10 | result := make([]string, 0)
11 | result = append(result, strings.Join(str, ""))
12 | for {
13 | var i int
14 | var j int
15 |
16 | for i = len(str) - 1; i >= 0; i-- {
17 | if i != 0 && str[i-1] < str[i] {
18 | break
19 | }
20 | }
21 |
22 | if i == -1 {
23 | break
24 | }
25 |
26 | for j = len(str) - 1; j >= 0; j-- {
27 | if str[i-1] < str[j] {
28 | str[i-1], str[j] = str[j], str[i-1]
29 | str = Reverse(str, i)
30 | result = append(result, strings.Join(str, ""))
31 | break
32 | }
33 | }
34 |
35 | }
36 | return result
37 | }
38 |
39 | // Reverse reverses a slice of string from it's length to given index
40 | func Reverse(str []string, index int) []string {
41 | newStr := strings.Join(str[0:index], "")
42 | for i := len(str) - 1; i >= index; i-- {
43 | newStr += str[i]
44 | }
45 | return strings.Split(newStr, "")
46 | }
47 |
--------------------------------------------------------------------------------
/algorithms/graphs/tsp/tsp_naive/undirected_graph/lo_permutations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strings"
5 | )
6 |
7 | // LOP performs Lexicographic Order Permutations on a given string.
8 | // Returns all possibilities as a slice of string.
9 | func LOP(str []string) []string {
10 | result := make([]string, 0)
11 | result = append(result, strings.Join(str, ""))
12 | for {
13 | var i int
14 | var j int
15 |
16 | for i = len(str) - 1; i >= 0; i-- {
17 | if i != 0 && str[i-1] < str[i] {
18 | break
19 | }
20 | }
21 |
22 | if i == -1 {
23 | break
24 | }
25 |
26 | for j = len(str) - 1; j >= 0; j-- {
27 | if str[i-1] < str[j] {
28 | str[i-1], str[j] = str[j], str[i-1]
29 | str = Reverse(str, i)
30 | result = append(result, strings.Join(str, ""))
31 | break
32 | }
33 | }
34 |
35 | }
36 | return result
37 | }
38 |
39 | // Reverse reverses a slice of string from it's length to given index
40 | func Reverse(str []string, index int) []string {
41 | newStr := strings.Join(str[0:index], "")
42 | for i := len(str) - 1; i >= index; i-- {
43 | newStr += str[i]
44 | }
45 | return strings.Split(newStr, "")
46 | }
47 |
--------------------------------------------------------------------------------
/algorithms/graphs/union_find/graph.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Edge represents an edge between two vertices
6 | type Edge struct {
7 | src string
8 | dest string
9 | }
10 |
11 | var graph map[string][]string
12 | var uniqueEdges []Edge
13 |
14 | func init() {
15 | graph = make(map[string][]string)
16 | uniqueEdges = make([]Edge, 0)
17 | }
18 |
19 | func addVertexToGraph(vtx string) {
20 | if graph[vtx] != nil {
21 | fmt.Println("\n-- Vertex already exists. --")
22 | return
23 | }
24 | vertices[vtx] = len(vertices)
25 | graph[vtx] = make([]string, 0)
26 | }
27 |
28 | func addEdgeToGraph(fromVtx, toVtx string) {
29 | if graph[fromVtx] == nil { // check if initial vertex exists
30 | fmt.Println("\n-- Initial vertex " + fromVtx + " does not exist. --")
31 | return
32 | }
33 | for i := range graph[fromVtx] { // check if edge already exists
34 | if graph[fromVtx][i] == toVtx {
35 | fmt.Println("\n-- Edge between " + fromVtx + " and " + toVtx + " already exists. --")
36 | return
37 | }
38 | }
39 | if graph[toVtx] == nil { // create new destination vertext if it does not exists
40 | graph[toVtx] = make([]string, 0)
41 | vertices[toVtx] = len(vertices)
42 | fmt.Println("\n-- Destination vertex " + toVtx + " created. --")
43 | }
44 |
45 | graph[fromVtx] = append(graph[fromVtx], toVtx)
46 | graph[toVtx] = append(graph[toVtx], fromVtx)
47 | uniqueEdges = append(uniqueEdges, Edge{src: fromVtx, dest: toVtx})
48 | }
49 |
50 | func addVertex() {
51 | var vtxName string
52 | fmt.Print("Enter the name of vertex: ")
53 | fmt.Scanf("%s\n", &vtxName)
54 | addVertexToGraph(vtxName)
55 | }
56 |
57 | func addEdge() {
58 | var fromVtx, toVtx string
59 | fmt.Print("Enter the initial vertex name: ")
60 | fmt.Scanf("%s\n", &fromVtx)
61 | fmt.Print("Enter the destination vertex name: ")
62 | fmt.Scanf("%s\n", &toVtx)
63 | addEdgeToGraph(fromVtx, toVtx)
64 | }
65 |
--------------------------------------------------------------------------------
/algorithms/graphs/union_find/union_find.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // UnionFind run union find algorithm and detects cycle in give graph
6 | func UnionFind() {
7 | flag := 0
8 | for i := 0; i < len(uniqueEdges); i++ {
9 | x := find(uniqueEdges[i].src)
10 | y := find(uniqueEdges[i].dest)
11 | if x == y {
12 | fmt.Println("\n-- Cycle FOUND between:", uniqueEdges[i].src, uniqueEdges[i].dest, ". --")
13 | flag = 1
14 | } else {
15 | union(x, y)
16 | }
17 | }
18 | if flag == 0 {
19 | fmt.Println("\n-- NO cycle found in graph. --")
20 | }
21 | }
22 |
23 | func find(i string) string {
24 | if parent[i] == "-1" {
25 | return i
26 | }
27 | return find(parent[i])
28 | }
29 |
30 | func union(vtx1, vtx2 string) {
31 | xset := find(vtx1)
32 | yset := find(vtx2)
33 | parent[xset] = yset
34 | }
35 |
36 | var parent map[string]string
37 | var vertices map[string]int
38 |
39 | func init() {
40 | vertices = make(map[string]int)
41 | parent = make(map[string]string)
42 | }
43 |
44 | func main() {
45 | fmt.Println("\n-- Union Find --")
46 | i := 0
47 | for i == 0 {
48 | fmt.Println("\n1. ADD A VERTEX")
49 | fmt.Println("2. ADD AN EDGE")
50 | fmt.Println("3. RUN UNION FIND")
51 | fmt.Println("4. EXIT")
52 | var choice int
53 | fmt.Print("Enter your choice: ")
54 | fmt.Scanf("%d\n", &choice)
55 | switch choice {
56 | case 1:
57 | addVertex()
58 | case 2:
59 | addEdge()
60 | case 3:
61 | UnionFind()
62 | case 4:
63 | i = 1
64 | default:
65 | fmt.Println("Command not recognized.")
66 | }
67 | }
68 | }
69 |
70 | func startUnionFind() {
71 | for i := range vertices {
72 | parent[i] = "-1"
73 | }
74 | UnionFind()
75 | }
76 |
77 | // addVertexToGraph("0")
78 | // addVertexToGraph("1")
79 | // addVertexToGraph("2")
80 | // addVertexToGraph("3")
81 | // addVertexToGraph("4")
82 | // addEdgeToGraph("0", "1")
83 | // addEdgeToGraph("0", "2")
84 | // addEdgeToGraph("1", "3")
85 | // addEdgeToGraph("1", "4")
86 | // addEdgeToGraph("3", "4")
87 |
88 | // addVertexToGraph("1")
89 | // addVertexToGraph("2")
90 | // addVertexToGraph("3")
91 | // addVertexToGraph("4")
92 | // addVertexToGraph("5")
93 | // addVertexToGraph("6")
94 | // addVertexToGraph("7")
95 | // addVertexToGraph("8")
96 | // addEdgeToGraph("1", "3")
97 | // addEdgeToGraph("1", "2")
98 | // addEdgeToGraph("2", "4")
99 | // addEdgeToGraph("3", "4")
100 | // addEdgeToGraph("2", "5")
101 | // addEdgeToGraph("5", "7")
102 | // addEdgeToGraph("5", "6")
103 | // addEdgeToGraph("8", "6")
104 | // addEdgeToGraph("8", "7")
105 |
106 | // addVertexToGraph("0")
107 | // addVertexToGraph("1")
108 | // addVertexToGraph("2")
109 | // addEdgeToGraph("0", "1")
110 | // addEdgeToGraph("1", "2")
111 | // addEdgeToGraph("0", "2")
112 |
--------------------------------------------------------------------------------
/algorithms/huffman_codes/heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // Node represents a single node in a heap
9 | type Node struct {
10 | char string
11 | freq int
12 | left *Node
13 | right *Node
14 | }
15 |
16 | type heap []Node
17 |
18 | // Insert inserts a node in a heap
19 | func (h heap) Insert(node Node) heap {
20 | h = append(h, node)
21 | h = h.minHeapify()
22 | return h
23 | }
24 |
25 | func (h heap) minHeapify() heap {
26 | idx := len(h) - 1
27 | element := h[idx]
28 | for idx > 0 {
29 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
30 | parent := h[parentIdx]
31 | if element.freq >= parent.freq {
32 | break
33 | }
34 | h[parentIdx] = element
35 | h[idx] = parent
36 | idx = parentIdx
37 | }
38 | return h
39 | }
40 |
41 | // ExtractMin will remove a node from heap
42 | func (h heap) ExtractMin() (*Node, heap) {
43 | if len(h) == 0 {
44 | fmt.Println("\n-- Heap is empty. --")
45 | return &Node{}, h
46 | }
47 | min := h[0]
48 | end := h[len(h)-1]
49 | h = h[0 : len(h)-1]
50 | if len(h) > 0 {
51 | h[0] = end
52 | h.bubbleDown()
53 | }
54 | return &min, h
55 | }
56 |
57 | func (h heap) bubbleDown() heap {
58 | idx := 0
59 | length := len(h)
60 | element := h[0]
61 | for {
62 | leftChildIdx := (2 * idx) + 1
63 | rightChildIdx := (2 * idx) + 2
64 | var leftChild, rightChild Node
65 | var swap int
66 |
67 | if leftChildIdx < length {
68 | leftChild = h[leftChildIdx]
69 | if leftChild.freq < element.freq {
70 | swap = leftChildIdx
71 | }
72 | }
73 | if rightChildIdx < length {
74 | rightChild = h[rightChildIdx]
75 | if (rightChild.freq < element.freq && swap == 0) || (rightChild.freq < leftChild.freq && swap != 0) {
76 | swap = rightChildIdx
77 | }
78 | }
79 |
80 | if swap == 0 {
81 | break
82 | }
83 | h[idx] = h[swap]
84 | h[swap] = element
85 | idx = swap
86 | }
87 | return h
88 | }
89 |
90 | func (h heap) insertNodes() heap {
91 | var char string
92 | var freq int
93 | fmt.Print("\nChar: ")
94 | fmt.Scanf("%s\n", &char)
95 | fmt.Print("Freq: ")
96 | fmt.Scanf("%d\n", &freq)
97 | h = h.Insert(Node{char: char, freq: freq})
98 | return h
99 | }
100 |
101 | func (h heap) display() {
102 | fmt.Println("")
103 | fmt.Println(h)
104 | }
105 |
--------------------------------------------------------------------------------
/algorithms/huffman_codes/huffman_codes.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | func (h heap) genHeap() *Node {
9 | var curr, prev *Node
10 | for len(h) > 1 {
11 | prev, h = h.ExtractMin()
12 | curr, h = h.ExtractMin()
13 | newNode := Node{left: prev, right: curr, freq: (prev.freq + curr.freq)}
14 | h = h.Insert(newNode)
15 | }
16 | return &h[0]
17 | }
18 |
19 | func (ht *Node) printHuffman() {
20 | var code []string
21 | code = make([]string, 0)
22 | ht.printHuffmanUtil(ht, code)
23 | }
24 |
25 | func (ht *Node) printHuffmanUtil(node *Node, code []string) {
26 | if node.left == nil && node.right == nil {
27 | // print
28 | fmt.Println("\n", node.char, "=>", strings.Join(code, ""))
29 | code = code[0:0]
30 | }
31 | if node.left != nil {
32 | code = append(code, "0")
33 | ht.printHuffmanUtil(node.left, code)
34 | code = code[0 : len(code)-1]
35 | }
36 | if node.right != nil {
37 | code = append(code, "1")
38 | ht.printHuffmanUtil(node.right, code)
39 | code = code[0 : len(code)-1]
40 | }
41 | }
42 |
43 | var n int
44 | var nodes []Node
45 | var huffTree *Node
46 |
47 | func main() {
48 | fmt.Println("\n-- Huffman Codes --")
49 |
50 | // initialize min heap
51 | h := make(heap, 0)
52 |
53 | fmt.Print("\nEnter the number of characters: ")
54 | fmt.Scanf("%d\n", &n)
55 | nodes = make([]Node, 0)
56 |
57 | fmt.Println("Start entering character and frequency:")
58 | for i := 0; i < n; i++ {
59 | h = h.insertNodes()
60 | }
61 |
62 | huffTree = h.genHeap()
63 | huffTree.printHuffman()
64 | }
65 |
66 | // a, 5
67 | // b, 9
68 | // c, 12
69 | // d, 13
70 | // e, 16
71 | // f, 45
72 |
--------------------------------------------------------------------------------
/algorithms/job_scheduling_gp/job_scheduling_gp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type job struct {
6 | profit float64
7 | deadline float64
8 | }
9 |
10 | // ScheduleJobs will schedule all the jobs maximizing the profit
11 | func ScheduleJobs() {
12 | count := max
13 | i := 0
14 | deadline := -1
15 | for count != 0 {
16 | if i == len(jobs)-1 { // a complete scan of all jobs is completed
17 | break
18 | }
19 | if deadline == -1 { // if deadline gets to -1 it can't be scheduled
20 | deadline = int(jobs[i].deadline)
21 | if deadline == 0 && result[deadline-1] == 0 { // if a job's deadline is 0
22 | result[deadline] = i + 1
23 | deadline = -1
24 | count--
25 | i++
26 | continue
27 | }
28 | }
29 | if deadline-1 != -1 && result[deadline-1] == 0 { // check if the job can scheduled
30 | result[deadline-1] = i + 1
31 | deadline = -1
32 | count--
33 | i++
34 | } else if deadline-1 == -1 { // check if the deadline is 0
35 | deadline = -1
36 | i++
37 | } else if result[deadline-1] != 0 {
38 | deadline--
39 | }
40 | }
41 | }
42 |
43 | var n int
44 | var jobs []job
45 | var result []int
46 | var max float64
47 |
48 | func main() {
49 | fmt.Println("\n-- Job Scheduling using Greedy Programming --")
50 |
51 | fmt.Print("\nEnter the number of jobs: ")
52 | fmt.Scanf("%d\n", &n)
53 | jobs = make([]job, n)
54 |
55 | fmt.Println("Start entering profits and deadlines of each job:")
56 | var temp float64
57 | for i := 0; i < n; i++ {
58 | fmt.Print("Profit: ")
59 | fmt.Scanf("%f\n", &temp)
60 | jobs[i].profit = temp
61 | fmt.Print("Deadline: ")
62 | fmt.Scanf("%f\n", &temp)
63 | jobs[i].deadline = temp
64 | if i == 0 {
65 | max = jobs[i].deadline
66 | } else if max < jobs[i].deadline {
67 | max = jobs[i].deadline
68 | }
69 | }
70 | result = make([]int, int(max))
71 | quicksort(0, n-1)
72 | ScheduleJobs()
73 | total := float64(0)
74 | for i := range result {
75 | total += jobs[result[i]-1].profit
76 | }
77 | fmt.Println("Jobs", result, "will be scheduled to have", total, "units of profit and will be taken in ascending order of their deadlines.")
78 | }
79 |
--------------------------------------------------------------------------------
/algorithms/job_scheduling_gp/quick_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // this quick sort algorithm will sort in descending order
4 | func partition(first, last int) int {
5 | pivot := jobs[first].profit
6 | i := first
7 | j := last + 1
8 |
9 | for i < j {
10 | i++
11 | j--
12 | for jobs[i].profit > pivot && i < last {
13 | i++
14 | }
15 | for jobs[j].profit < pivot && j > first {
16 | j--
17 | }
18 | if i < j {
19 | jobs[i].profit, jobs[j].profit = jobs[j].profit, jobs[i].profit
20 | }
21 | }
22 | jobs[j].profit, jobs[first].profit = jobs[first].profit, jobs[j].profit
23 | return j
24 | }
25 |
26 | func quicksort(first, last int) {
27 | var sp int
28 | if first < last {
29 | sp = partition(first, last)
30 | quicksort(first, sp-1)
31 | quicksort(sp+1, last)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/algorithms/lcm/lcm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("\n-- Least Common Multiple --")
7 | var m, n, lcm int
8 | fmt.Print("\nEnter the first number: ")
9 | fmt.Scanf("%d\n", &m)
10 | fmt.Print("Enter the second number: ")
11 | fmt.Scanf("%d\n", &n)
12 | if n < m {
13 | lcm = findLCM(m, n)
14 | } else {
15 | lcm = findLCM(n, m)
16 | }
17 | fmt.Println("Least Common Multiple of", m, "and", n, "is:", lcm)
18 | }
19 |
20 | func findLCM(m, n int) int {
21 | val := findGCD(m, n)
22 | return (m * n) / val
23 | }
24 |
25 | func findGCD(m, n int) int {
26 | if n == 0 {
27 | return m
28 | }
29 | return findGCD(n, m%n)
30 | }
31 |
--------------------------------------------------------------------------------
/algorithms/lcs/iterative_dp/lcs_iterative_dp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | "strings"
7 | )
8 |
9 | // LCS recursive solution of lcs problem
10 | func LCS() string {
11 | for i := range sequence {
12 | for j := range sequence[i] {
13 | if i == 0 || j == 0 {
14 | continue
15 | } else if string(str01[i]) == string(str02[j]) {
16 | sequence[i][j] = 1 + sequence[i-1][j-1]
17 | } else {
18 | sequence[i][j] = int(math.Max(float64(sequence[i-1][j]), float64(sequence[i][j-1])))
19 | }
20 | }
21 | }
22 |
23 | i := len(str01) - 1
24 | j := len(str02) - 1
25 | str := make([]string, sequence[i][j])
26 | for {
27 | if sequence[i][j] == 0 {
28 | break
29 | } else if sequence[i-1][j] == sequence[i][j] {
30 | i--
31 | } else if sequence[i][j-1] == sequence[i][j] {
32 | j--
33 | } else {
34 | str[sequence[i][j]-1] += string(str02[j])
35 | i--
36 | j--
37 | }
38 | }
39 | return strings.Join(str, "")
40 | }
41 |
42 | var str01 string
43 | var str02 string
44 | var sequence [][]int
45 |
46 | func main() {
47 | fmt.Println("\n-- Longest Common Subsequence --")
48 | fmt.Print("\nEnter the first string: ")
49 | fmt.Scanf("%s\n", &str01)
50 | fmt.Print("Enter the second string: ")
51 | fmt.Scanf("%s\n", &str02)
52 | str01 = "\n" + str01
53 | str02 = "\n" + str02
54 | sequence = make([][]int, len(str01))
55 | for i := range sequence {
56 | sequence[i] = make([]int, len(str02))
57 | }
58 | str := LCS()
59 | i := len(str01) - 1
60 | j := len(str02) - 1
61 |
62 | fmt.Println("The Longest Common Subsequence is of length", sequence[i][j], "which is", "'"+str+"'.")
63 | }
64 |
--------------------------------------------------------------------------------
/algorithms/lo_permutations/lo_permutations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | "strings"
7 | )
8 |
9 | func main() {
10 | fmt.Println("-- Lexicographic Ordering Permutations --")
11 | var str string
12 | fmt.Print("Enter a string: ")
13 | fmt.Scanf("%s\n", &str)
14 | arr := strings.Split(str, "")
15 | sort.Strings(arr)
16 | result := LOP(arr)
17 | for i := 0; i < len(result); i++ {
18 | fmt.Println(i+1, "-", result[i])
19 | }
20 | }
21 |
22 | // LOP performs Lexicographic Order Permutations on a given string.
23 | // Returns all possibilities as a slice of string.
24 | func LOP(str []string) []string {
25 | result := make([]string, 0)
26 | result = append(result, strings.Join(str, ""))
27 | for {
28 | var i int
29 | var j int
30 |
31 | for i = len(str) - 1; i >= 0; i-- {
32 | if i != 0 && str[i-1] < str[i] {
33 | break
34 | }
35 | }
36 |
37 | if i == -1 {
38 | break
39 | }
40 |
41 | for j = len(str) - 1; j >= 0; j-- {
42 | if str[i-1] < str[j] {
43 | str[i-1], str[j] = str[j], str[i-1]
44 | str = Reverse(str, i)
45 | result = append(result, strings.Join(str, ""))
46 | break
47 | }
48 | }
49 |
50 | }
51 | return result
52 | }
53 |
54 | // Reverse reverses a slice of string from it's length to given index
55 | func Reverse(str []string, index int) []string {
56 | newStr := strings.Join(str[:index], "")
57 | for i := len(str) - 1; i >= index; i-- {
58 | newStr += str[i]
59 | }
60 | return strings.Split(newStr, "")
61 | }
62 |
--------------------------------------------------------------------------------
/algorithms/longest_palindrome_substring/brute_force/brute_force.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | func main() {
9 | fmt.Println("\n-- Longest Palindrome Substring Brute Force Technique --")
10 |
11 | var str string
12 | var txt []string
13 |
14 | fmt.Print("\nEnter a text string: ")
15 | fmt.Scanf("%s\n", &str)
16 |
17 | txt = strings.Split(str, "")
18 | str = "#" + strings.Join(txt, "#") + "#"
19 | txt = strings.Split(str, "")
20 |
21 | fmt.Println("\nPalindrome\\s are:")
22 | p := BruteForce(txt)
23 | for i := range p {
24 | fmt.Println("'"+i+"'", "of length", p[i])
25 | }
26 | }
27 |
28 | // BruteForce finds Longest Palindrome Substring in a given string using Brute Force technique
29 | func BruteForce(txt []string) map[string]int {
30 |
31 | pMap := make(map[string]int)
32 |
33 | for i := 0; i < len(txt); i++ {
34 |
35 | k := i + 1
36 |
37 | for j := i; j >= 0 && k <= len(txt); j-- {
38 |
39 | subStr := txt[j:k]
40 | flag := 0
41 |
42 | for p := 0; p < len(subStr); p++ {
43 | if subStr[p] != subStr[len(subStr)-1-p] {
44 | flag = 1
45 | break
46 | }
47 | }
48 |
49 | if flag == 1 {
50 | flag = 0
51 | } else {
52 | pMap[strings.Join(subStr, "")] = len(subStr)
53 | }
54 | k++
55 |
56 | }
57 |
58 | }
59 |
60 | for i := range pMap {
61 | temp := strings.Split(i, "#")
62 | str := strings.Join(temp, "")
63 | delete(pMap, i)
64 | pMap[str] = len(str)
65 | }
66 |
67 | // key "" generated for # as palindrome in hash map
68 | delete(pMap, "")
69 |
70 | return pMap
71 | }
72 |
73 | // Test strings
74 | //
75 | // ABABABA
76 | // [BABAB:5 ABABABA:7 B:1 A:1 BAB:3 ABABA:5 ABA:3]
77 | //
78 | // ABBAABBA
79 | // [A:1 BAAB:4 ABBA:4 AA:2 BBAABB:6 ABBAABBA:8 B:1 BB:2]
80 | //
81 | // FORGEEKSSKEEGFOR
82 | // [SS:2 R:1 G:1 O:1 EE:2 EEKSSKEE:8 S:1 GEEKSSKEEG:10 KSSK:4 F:1 K:1 EKSSKE:6 E:1]
83 | //
84 | // ABCBABCBABCBA
85 | // [BCBABCBABCB:11 BAB:3 B:1 A:1 BCB:3 C:1 ABCBA:5 BABCBAB:7 CBABC:5 BCBABCB:7 CBABCBABC:9 ABCBABCBABCBA:13 ABCBABCBA:9]
86 | //
87 | // ABAABA
88 | // [ABA:3 ABAABA:6 B:1 BAAB:4 AA:2 A:1]
89 |
--------------------------------------------------------------------------------
/algorithms/longest_palindrome_substring/manchers/manchers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | "strings"
7 | )
8 |
9 | func main() {
10 | fmt.Println("\n-- Longest Palindrome Substring Mancher's Algorithm --")
11 |
12 | var str string
13 | var txt []string
14 |
15 | fmt.Print("\nEnter a text string: ")
16 | fmt.Scanf("%s\n", &str)
17 |
18 | txt = strings.Split(str, "")
19 | str = "^" + "#" + strings.Join(txt, "#") + "#" + "$"
20 | txt = strings.Split(str, "")
21 |
22 | fmt.Println("\nPalindrome\\s are:")
23 | p := Manchers(txt)
24 | for i := range p {
25 | fmt.Println("'"+i+"'", "of length", p[i])
26 | }
27 | }
28 |
29 | // Manchers performs mancher's algorithm which finds longest palindrome substring in a given string
30 | func Manchers(txt []string) map[string]int {
31 | subStr := make([]int, len(txt))
32 | c := 0
33 | r := 0
34 |
35 | for i := 1; i < len(txt)-1; i++ {
36 | mirror := 2*c - i
37 | if i < r {
38 | subStr[i] = int(math.Min(float64(r-i), float64(subStr[mirror])))
39 | }
40 |
41 | for txt[i+(1+subStr[i])] == txt[i-(1+subStr[i])] {
42 | subStr[i]++
43 | }
44 |
45 | if i+subStr[i] > r {
46 | c = i
47 | r = i + subStr[i]
48 | }
49 |
50 | }
51 |
52 | return findPalindromes(txt, subStr)
53 | }
54 |
55 | func findPalindromes(txt []string, subStr []int) map[string]int {
56 | pMap := make(map[string]int)
57 |
58 | for i := 0; i < len(subStr); i++ {
59 | if subStr[i] == 0 {
60 | continue
61 | }
62 | j := i - 1
63 | k := i + 2
64 | jLen := i - subStr[i]
65 | kLen := i + subStr[i] + 1
66 | for j >= jLen && k <= kLen {
67 | temp := strings.Join(txt[j:k], "")
68 | pMap[temp] = 0
69 | j--
70 | k++
71 | }
72 | }
73 |
74 | for i := range pMap {
75 | temp := strings.Split(i, "#")
76 | str := strings.Join(temp, "")
77 |
78 | // delete first then insert new map value
79 | delete(pMap, i)
80 | pMap[str] = len(str)
81 | }
82 |
83 | return pMap
84 | }
85 |
86 | // Test strings
87 | //
88 | // ABABABA
89 | // [BABAB:5 ABABABA:7 B:1 A:1 BAB:3 ABABA:5 ABA:3]
90 | //
91 | // ABBAABBA
92 | // [A:1 BAAB:4 ABBA:4 AA:2 BBAABB:6 ABBAABBA:8 B:1 BB:2]
93 | //
94 | // FORGEEKSSKEEGFOR
95 | // [SS:2 R:1 G:1 O:1 EE:2 EEKSSKEE:8 S:1 GEEKSSKEEG:10 KSSK:4 F:1 K:1 EKSSKE:6 E:1]
96 | //
97 | // ABCBABCBABCBA
98 | // [BCBABCBABCB:11 BAB:3 B:1 A:1 BCB:3 C:1 ABCBA:5 BABCBAB:7 CBABC:5 BCBABCB:7 CBABCBABC:9 ABCBABCBABCBA:13 ABCBABCBA:9]
99 | //
100 | // ABAABA
101 | // [ABA:3 ABAABA:6 B:1 BAAB:4 AA:2 A:1]
102 |
--------------------------------------------------------------------------------
/algorithms/making_change_dp/making_change_dp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // MakeChange will generate the necessary matrix which will then be evaluated to know
9 | // the number of coins and which coins will be required to have a given change
10 | func MakeChange() {
11 | for i := 0; i < len(matrix); i++ {
12 | for j := 0; j < len(matrix[i]); j++ {
13 | if i == 0 || j == 0 {
14 | continue
15 | } else if i == 1 {
16 | matrix[i][j] = 1 + matrix[i][j-int(coins[i-1])]
17 | } else if j < int(coins[i-1]) {
18 | matrix[i][j] = matrix[i-1][j]
19 | } else {
20 | matrix[i][j] = math.Min(matrix[i-1][j], 1+matrix[i][j-int(coins[i-1])])
21 | }
22 | }
23 | }
24 | fmt.Println("\nMatrix formed:")
25 | for i := 0; i < len(matrix); i++ {
26 | for j := 0; j < len(matrix[i]); j++ {
27 | fmt.Print(matrix[i][j], " ")
28 | }
29 | fmt.Println()
30 | }
31 | i := len(matrix) - 1
32 | j := len(matrix[0]) - 1
33 | result := make([]float64, 0)
34 | count := matrix[i][j]
35 | for count != 0 {
36 | if matrix[i-1][j] == count {
37 | i--
38 | } else {
39 | j -= int(coins[i-1])
40 | result = append(result, coins[i-1])
41 | count--
42 | }
43 | }
44 | fmt.Println("You will require", len(result), "coins of values", result, "to make a change for", change, ".")
45 | }
46 |
47 | var change float64
48 | var numCoins float64
49 | var coins []float64
50 | var matrix [][]float64
51 |
52 | func main() {
53 | fmt.Println("\n-- Making Change Problem using Dynamic Programming. --")
54 | fmt.Print("Enter the value for the amount of change you want: ")
55 | fmt.Scanf("%f\n", &change)
56 | fmt.Print("Enter the number of coins you have: ")
57 | fmt.Scanf("%f\n", &numCoins)
58 | var coin float64
59 | fmt.Println("Start enter the values of these coins in increasing order:")
60 | for i := 0; i < int(numCoins); i++ {
61 | fmt.Scanf("%f\n", &coin)
62 | coins = append(coins, coin)
63 | }
64 | matrix = make([][]float64, int(numCoins)+1)
65 | for i := 0; i < len(matrix); i++ {
66 | matrix[i] = make([]float64, int(change)+1)
67 | for j := range matrix[i] {
68 | matrix[i][j] = float64(0)
69 | }
70 | }
71 | MakeChange()
72 | }
73 |
--------------------------------------------------------------------------------
/algorithms/order_statistics/naive_approach/heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func maxHeapify() {
9 | idx := len(arr) - 1
10 | element := arr[idx]
11 | for idx > 0 {
12 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
13 | parent := arr[parentIdx]
14 | if element <= parent {
15 | break
16 | }
17 | arr[parentIdx] = element
18 | arr[idx] = parent
19 | idx = parentIdx
20 | }
21 | }
22 |
23 | // ExtractMax will remove a node from heap
24 | func ExtractMax() int {
25 | if len(arr) == 0 || arr[0] == 0 {
26 | fmt.Println("\n-- Heap is empty. --")
27 | return 0
28 | }
29 | max := arr[0]
30 | end := arr[len(arr)-1]
31 | arr = arr[0 : len(arr)-1]
32 | if len(arr) > 0 {
33 | arr[0] = end
34 | bubbleDown()
35 | }
36 | return max
37 | }
38 |
39 | func bubbleDown() {
40 | idx := 0
41 | length := len(arr)
42 | element := arr[0]
43 | for {
44 | leftChildIdx := (2 * idx) + 1
45 | rightChildIdx := (2 * idx) + 2
46 | var leftChild, rightChild, swap int
47 |
48 | if leftChildIdx < length {
49 | leftChild = arr[leftChildIdx]
50 | if leftChild > element {
51 | swap = leftChildIdx
52 | }
53 | }
54 | if rightChildIdx < length {
55 | rightChild = arr[rightChildIdx]
56 | if (rightChild > element && swap == 0) || (rightChild > leftChild && swap != 0) {
57 | swap = rightChildIdx
58 | }
59 | }
60 |
61 | if swap == 0 {
62 | break
63 | }
64 | arr[idx] = arr[swap]
65 | arr[swap] = element
66 | idx = swap
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/algorithms/order_statistics/naive_approach/naive_approach.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | fmt.Println("\n-- Order Statistics Naive Approach --")
9 |
10 | // initialization
11 | var size int
12 | newArr := make([]int, 0)
13 | var k int
14 |
15 | // user inputs
16 | fmt.Print("\nEnter the size of array: ")
17 | fmt.Scanf("%d\n", &size)
18 | fmt.Println("Start entering elements:")
19 | for i := 0; i < size; i++ {
20 | var value int
21 | fmt.Scanf("%d\n", &value)
22 | newArr = append(newArr, value)
23 | }
24 | fmt.Print("Enter the value of k: ")
25 | fmt.Scanf("%d\n", &k)
26 |
27 | naiveSelect(newArr, k)
28 |
29 | fmt.Println(k, "smallest element is:", arr[0])
30 | }
31 |
32 | func naiveSelect(newArr []int, k int) {
33 | for i := 0; i < k; i++ {
34 | arr = append(arr, newArr[i])
35 | maxHeapify()
36 | }
37 | for i := k; i < len(newArr); i++ {
38 | if arr[0] < newArr[i] {
39 | continue
40 | }
41 | arr = append(arr, newArr[i])
42 | maxHeapify()
43 | ExtractMax()
44 | }
45 | }
46 |
47 | // sorted - {1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 19}
48 | // var newArr = []int{5, 15, 8, 3, 1, 9, 10, 6, 7, 12, 14, 2, 16, 19}
49 |
--------------------------------------------------------------------------------
/algorithms/order_statistics/quick_select/quick_select.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math/rand"
6 | "time"
7 | )
8 |
9 | func main() {
10 | fmt.Println("\n-- Order Statistics Quick Select --")
11 |
12 | // initializations
13 | var size, k int
14 | arr := make([]int, 0)
15 |
16 | // user inputs
17 | fmt.Print("\nEnter the size of array: ")
18 | fmt.Scanf("%d\n", &size)
19 | fmt.Println("Start entering elements:")
20 | for i := 0; i < size; i++ {
21 | var value int
22 | fmt.Scanf("%d\n", &value)
23 | arr = append(arr, value)
24 | }
25 | fmt.Print("Enter the value for k: ")
26 | fmt.Scanf("%d\n", &k)
27 |
28 | value := QuickSelect(arr, k)
29 | fmt.Println(k, "smallest element is:", value)
30 | }
31 |
32 | // QuickSelect finds kth smallest element in an array using quick sort - partially
33 | func QuickSelect(arr []int, k int) int {
34 | if len(arr) == 1 {
35 | return arr[0]
36 | }
37 |
38 | pos := partition(arr)
39 |
40 | if pos == k-1 {
41 | return arr[pos]
42 | } else if k-1 < pos {
43 | return QuickSelect(arr[:pos], k)
44 | }
45 |
46 | return QuickSelect(arr[pos+1:], k-pos-1)
47 | }
48 |
49 | func partition(arr []int) int {
50 |
51 | // generate a random number, time as a seed value
52 | rand.Seed(time.Now().UnixNano())
53 | n := rand.Intn(len(arr) - 1)
54 |
55 | // push the element to last
56 | arr[n], arr[len(arr)-1] = arr[len(arr)-1], arr[n]
57 | n = len(arr) - 1
58 |
59 | pivot := arr[n]
60 | index := 0
61 | for i := 0; i < n; i++ {
62 | if arr[i] < pivot {
63 | arr[i], arr[index] = arr[index], arr[i]
64 | index++
65 | }
66 | }
67 | arr[index], arr[n] = arr[n], arr[index]
68 | return index
69 | }
70 |
71 | // sorted - {1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 19}
72 | // var arr = []int{5, 15, 8, 3, 1, 9, 10, 6, 7, 12, 14, 2, 16, 19}
73 |
--------------------------------------------------------------------------------
/algorithms/order_statistics/worst_case_linear_time/wclt.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | "sort"
7 | )
8 |
9 | func main() {
10 | fmt.Println("\n-- Worst Case Linear Time Order Statistics --")
11 | arr := make([]float64, 0)
12 | var value int
13 | var n int
14 | var k int
15 | fmt.Print("\nEnter the size of an array: ")
16 | fmt.Scanf("%d\n", &n)
17 | fmt.Println("Start entering elements:")
18 | for i := 0; i < n; i++ {
19 | fmt.Scanf("%d\n", &value)
20 | arr = append(arr, float64(value))
21 | }
22 | fmt.Print("Enter the value for k: ")
23 | fmt.Scanf("%d\n", &k)
24 | if k < 1 || k >= len(arr) {
25 | fmt.Println("You must enter a valid value for k.")
26 | return
27 | }
28 | fmt.Println(k, "smallest element is:", kthSmallest(arr, k))
29 | }
30 |
31 | // WCLT Worst Case Linear Time Order Statistics
32 | func kthSmallest(arr []float64, k int) float64 {
33 | if len(arr) == 1 {
34 | return arr[0]
35 | }
36 |
37 | median := make([]float64, 0)
38 | upto := int(math.Ceil(float64(len(arr)) / 5))
39 | // dividing array in n/5 subgroups
40 | for i := 0; i < upto; i++ {
41 | if (i*5)+5 > len(arr) {
42 | newArr := arr[i*5:]
43 | sort.Float64s(newArr)
44 | median = append(median, findMedian(newArr, len(newArr)))
45 | } else {
46 | newArr := arr[i*5 : (i*5)+5]
47 | sort.Float64s(newArr)
48 | median = append(median, findMedian(newArr, 5))
49 | }
50 | }
51 |
52 | // finding median of medians
53 | medianOfMedian := kthSmallest(median, len(median)/2)
54 |
55 | rank := findRank(arr, medianOfMedian)
56 |
57 | pos := partition(arr, rank)
58 |
59 | if pos == k-1 {
60 | return arr[pos]
61 | } else if pos > k-1 {
62 | return kthSmallest(arr[:pos], k)
63 | }
64 |
65 | return kthSmallest(arr[pos+1:], k-pos-1)
66 | }
67 |
68 | func partition(arr []float64, rank int) int {
69 | arr[rank], arr[len(arr)-1] = arr[len(arr)-1], arr[rank]
70 | pivot := arr[len(arr)-1]
71 | index := 0
72 | for i := 0; i < len(arr)-1; i++ {
73 | if arr[i] < pivot {
74 | arr[i], arr[index] = arr[index], arr[i]
75 | index++
76 | }
77 | }
78 | arr[index], arr[len(arr)-1] = arr[len(arr)-1], arr[index]
79 | return index
80 | }
81 |
82 | func findMedian(arr []float64, n int) float64 {
83 | return arr[n/2]
84 | }
85 |
86 | func findRank(arr []float64, value float64) int {
87 | for i := 0; i < len(arr); i++ {
88 | if arr[i] == value {
89 | return i
90 | }
91 | }
92 | return -1
93 | }
94 |
95 | // Array
96 | // {5, 15, 8, 3, 1, 9, 10, 6, 7, 12, 14, 2, 16, 19}
97 | // sorted - {1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 19}
98 |
--------------------------------------------------------------------------------
/algorithms/power_set/power_set.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | "strings"
7 | )
8 |
9 | func main() {
10 | fmt.Println("\n-- Generating Power Set (Set of Subsets)--")
11 |
12 | var value int
13 |
14 | fmt.Print("\nEnter a value: ")
15 | fmt.Scanf("%d\n", &value)
16 |
17 | list := PowerSet(value)
18 |
19 | fmt.Println("All possible subsets upto", value, "are:")
20 | for i := 0; i < len(list); i++ {
21 | str := strings.Split(list[i], "")
22 | fmt.Println("{" + strings.Join(str, ", ") + "}")
23 | }
24 | }
25 |
26 | // PowerSet generates a set of all subsets of a given integer
27 | func PowerSet(n int) []string {
28 |
29 | if n == 0 {
30 | return []string{"0"}
31 | }
32 |
33 | list := PowerSet(n - 1)
34 |
35 | newList := make([]string, 0)
36 |
37 | str := strconv.Itoa(n)
38 | newList = append(newList, list...)
39 | newList = append(newList, str)
40 | for i := 1; i < len(list); i++ {
41 | newList = append(newList, list[i]+str)
42 | }
43 | return newList
44 | }
45 |
--------------------------------------------------------------------------------
/algorithms/searching/binary_search/binary_search.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func binarySearch(size, key int) int {
6 | var low, middle, high, index int
7 | low = 0
8 | high = size - 1
9 |
10 | for low <= high {
11 | middle = (low + high) / 2
12 | if arr[middle] < key {
13 | low = middle + 1
14 | } else if arr[middle] > key {
15 | high = middle - 1
16 | } else if arr[middle] == key {
17 | index = middle + 1
18 | return index
19 | }
20 | }
21 | return -1
22 | }
23 |
24 | var arr []int
25 |
26 | func main() {
27 | var size, element, key int
28 | fmt.Println("\n-- Binary Search --")
29 | fmt.Print("\nEnter the size of an array: ")
30 | fmt.Scanf("%d\n", &size)
31 | fmt.Println("Start entering elements in sorted manner:")
32 | for i := 0; i < size; i++ {
33 | fmt.Scanf("%d\n", &element)
34 | arr = append(arr, element)
35 | }
36 | fmt.Print("Enter the search key: ")
37 | fmt.Scanf("%d\n", &key)
38 |
39 | index := binarySearch(size, key)
40 | if index == -1 {
41 | fmt.Println("Search key not found.")
42 | } else {
43 | fmt.Println("Search key found at index:")
44 | fmt.Println(index)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/algorithms/searching/interpolation_search/interpolation_search.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("\n-- Interpolation Search --")
7 |
8 | var size, key int
9 | arr := make([]int, 0)
10 |
11 | fmt.Print("\nEnter the size of array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering elements in sorted order:")
14 | for i := 0; i < size; i++ {
15 | var value int
16 | fmt.Scanf("%d\n", &value)
17 | arr = append(arr, value)
18 | }
19 | fmt.Print("Enter the value for key: ")
20 | fmt.Scanf("%d\n", &key)
21 |
22 | pos := InterpolationSearch(arr, key)
23 |
24 | if pos == -1 {
25 | fmt.Println("\nKey", key, "not found in given array.")
26 | } else {
27 | fmt.Println("\nKey", key, "found at position", pos, "in given array.")
28 | }
29 | }
30 |
31 | // InterpolationSearch searches for a key in an sorted array
32 | func InterpolationSearch(arr []int, key int) int {
33 | l := 0
34 | h := len(arr) - 1
35 |
36 | for arr[l] <= key && arr[h] >= key {
37 | pos := l + (((key - arr[l]) * (h - l)) / (arr[h] - arr[l]))
38 |
39 | if arr[pos] == key {
40 | return pos + 1
41 | } else if key < arr[pos] {
42 | h = pos - 1
43 | } else if key > arr[pos] {
44 | l = pos + 1
45 | }
46 | }
47 | return -1
48 | }
49 |
50 | // var arr = []int{10, 20, 25, 35, 50, 70, 85, 100, 110, 120, 125}
51 | // var arr = []int{5, 10, 15, 20, 25, 30, 35, 40, 45, 50}
52 |
--------------------------------------------------------------------------------
/algorithms/searching/linear_search/linear_search.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func linearSearch(size, key int) []int {
6 | var index []int
7 | for i := 0; i < size; i++ {
8 | if key == arr[i] {
9 | index = append(index, i+1)
10 | }
11 | }
12 | return index
13 | }
14 |
15 | var arr []int
16 |
17 | func main() {
18 | var size, element, key int
19 | fmt.Println("\n-- Linear Search --")
20 | fmt.Print("\nEnter the size of an array: ")
21 | fmt.Scanf("%d\n", &size)
22 | fmt.Println("Start entering elements in sorted manner:")
23 | for i := 0; i < size; i++ {
24 | fmt.Scanf("%d\n", &element)
25 | arr = append(arr, element)
26 | }
27 | fmt.Print("Enter the search key: ")
28 | fmt.Scanf("%d\n", &key)
29 | index := linearSearch(size, key)
30 | if len(index) == 0 {
31 | fmt.Println("Key not fount")
32 | } else {
33 | fmt.Println("Key found at following index/indices:")
34 | fmt.Println(index)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/algorithms/searching/ternary_search/ternary_search.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("\n-- Ternary Search --")
7 |
8 | var size, key int
9 | arr := make([]int, 0)
10 |
11 | fmt.Print("\nEnter the size of array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering elements in sorted order:")
14 | for i := 0; i < size; i++ {
15 | var value int
16 | fmt.Scanf("%d\n", &value)
17 | arr = append(arr, value)
18 | }
19 | fmt.Print("Enter the value for key: ")
20 | fmt.Scanf("%d\n", &key)
21 |
22 | pos := TernarySearch(arr, 0, size-1, key)
23 |
24 | if pos == -1 {
25 | fmt.Println("\nKey", key, "not found in given array.")
26 | } else {
27 | fmt.Println("\nKey", key, "found at position", pos, "in given array.")
28 | }
29 |
30 | }
31 |
32 | // TernarySearch searches for a key in a given array
33 | func TernarySearch(arr []int, l, h, key int) int {
34 | if h < l {
35 | return -1
36 | }
37 |
38 | mid1 := l + (h-l)/3
39 | mid2 := h - (h-l)/3
40 |
41 | if arr[mid1] == key {
42 | return mid1 + 1
43 | } else if arr[mid2] == key {
44 | return mid2 + 1
45 | } else if key < arr[mid1] {
46 | return TernarySearch(arr, l, mid1-1, key)
47 | } else if key > arr[mid1] && key < arr[mid2] {
48 | return TernarySearch(arr, mid1+1, mid2-1, key)
49 | } else if key > arr[mid2] {
50 | return TernarySearch(arr, mid2+1, h, key)
51 | }
52 | return -1
53 | }
54 |
55 | // var arr = []int{1, 3, 4, 6, 8, 9, 12, 15, 17, 18, 23, 25, 27, 31, 32}
56 |
--------------------------------------------------------------------------------
/algorithms/sieve_of_eratosthenes/sieve_of_eratosthenes.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func main() {
9 | fmt.Println("-- Sieve of Eratosthenes: Generating consecutive primes numbers not exceeding n --")
10 | var n int
11 | fmt.Print("Enter the number greater than 1: ")
12 | fmt.Scanf("%d\n", &n)
13 | arr := Sieve(n)
14 | fmt.Println("Consecutive prime number not exceeding", n, "are: ")
15 | fmt.Println(arr)
16 | }
17 |
18 | // Sieve implements Sieve of Eratosthenes algorithm
19 | func Sieve(n int) []int {
20 | arr := make([]int, 0)
21 | limit := int(math.Floor(math.Sqrt(float64(n))))
22 |
23 | for i := 0; i <= n; i++ {
24 | arr = append(arr, i)
25 | }
26 |
27 | arr[1] = 0
28 |
29 | for i := 2; i <= limit; i++ {
30 | if arr[i] != 0 {
31 | j := i * i
32 | for j <= n {
33 | arr[j] = 0
34 | j += i
35 | }
36 | }
37 | }
38 |
39 | newArr := make([]int, 0)
40 |
41 | for i := 0; i < len(arr); i++ {
42 | if arr[i] != 0 {
43 | newArr = append(newArr, arr[i])
44 | }
45 | }
46 |
47 | return newArr
48 | }
49 |
--------------------------------------------------------------------------------
/algorithms/sorting/binary_insertion_sort/binary_insertion_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // InsertionSort performs insertion sort while finding the right position for the key element to be inserted
6 | // using BinarySearch
7 | func InsertionSort() {
8 | var lock int
9 | for i := 0; i < n-1; i++ {
10 | j := i
11 | key := elements[i+1]
12 | lock = BinarySearch(elements, key, 0, j)
13 | for j >= lock {
14 | elements[j+1] = elements[j]
15 | j--
16 | }
17 | elements[j+1] = key
18 | }
19 | }
20 |
21 | var n int
22 | var elements []int
23 |
24 | func main() {
25 | fmt.Println("\n-- Binary Insertion Sort --")
26 | fmt.Print("\nEnter the number of elements: ")
27 | fmt.Scanf("%d\n", &n)
28 | elements = make([]int, n)
29 | var temp int
30 | fmt.Println("Start entering the elements:")
31 | for i := 0; i < n; i++ {
32 | fmt.Scanf("%d\n", &temp)
33 | elements[i] = temp
34 | }
35 | InsertionSort()
36 | fmt.Println("Sorted Array is: ")
37 | fmt.Println(elements)
38 | }
39 |
40 | // BinarySearch performs binary search on given array
41 | func BinarySearch(arr []int, item, low, high int) int {
42 | if high <= low {
43 | if item > arr[low] {
44 | return low + 1
45 | }
46 | return low
47 | }
48 | mid := (low + high) / 2
49 | if item == arr[mid] {
50 | return mid + 1
51 | }
52 | if item > arr[mid] {
53 | return BinarySearch(arr, item, mid+1, high)
54 | }
55 | return BinarySearch(arr, item, low, mid-1)
56 | }
57 |
--------------------------------------------------------------------------------
/algorithms/sorting/bubble_sort/bubble_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | var size int
9 | var element int
10 | fmt.Println("\n-- Bubble Sort --")
11 | fmt.Print("\nEnter the size of an array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering elements:")
14 | for i := 0; i < size; i++ {
15 | fmt.Scanf("%d\n", &element)
16 | arr = append(arr, element)
17 | }
18 |
19 | // sorting
20 | for i := size - 1; i >= 0; i-- {
21 | for j := 0; j < i; j++ {
22 | if arr[j] > arr[j+1] {
23 | arr[j], arr[j+1] = arr[j+1], arr[j]
24 | }
25 | }
26 | }
27 |
28 | fmt.Println("Sorted Array is:")
29 | fmt.Println(arr)
30 | }
31 |
--------------------------------------------------------------------------------
/algorithms/sorting/bucket_sort/bucket_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // InsertionSort performs insertion sort on each bucket
9 | func InsertionSort(a []float64, n int) []float64 {
10 | for i := 0; i < n-1; i++ {
11 | j := i
12 | key := a[i+1]
13 | for j >= 0 && key < a[j] {
14 | a[j+1] = a[j]
15 | j--
16 | }
17 | a[j+1] = key
18 | }
19 | return a
20 | }
21 |
22 | // BucketSort sort the array using bucket sort algorithm
23 | func BucketSort() {
24 | bucket = make([][]float64, size)
25 | for i := 0; i < size; i++ {
26 | index := int(math.Floor((arr[i] / max) * (float64(size - 1))))
27 | bucket[index] = append(bucket[index], arr[i])
28 | }
29 |
30 | for i := 0; i < size; i++ {
31 | if i == 0 {
32 | bucket[0] = InsertionSort(bucket[i], len(bucket[i]))
33 | } else {
34 | bucket[0] = append(bucket[0], InsertionSort(bucket[i], len(bucket[i]))...)
35 | }
36 | }
37 | }
38 |
39 | var size int
40 | var max float64
41 | var arr []float64
42 | var bucket [][]float64
43 |
44 | func init() {
45 | arr = make([]float64, 0)
46 | bucket = make([][]float64, 0)
47 | }
48 |
49 | func main() {
50 | fmt.Println("\n-- Insertion Sort --")
51 | fmt.Print("Enter the size of an array: ")
52 | fmt.Scanf("%d\n", &size)
53 | fmt.Println("Start entering the elements:")
54 | var temp float64
55 | for i := 0; i < size; i++ {
56 | if i == 0 {
57 | max = temp
58 | }
59 | fmt.Scanf("%f\n", &temp)
60 | arr = append(arr, temp)
61 | if max < temp {
62 | max = temp
63 | }
64 | }
65 |
66 | BucketSort()
67 |
68 | fmt.Println(bucket[0])
69 | }
70 |
--------------------------------------------------------------------------------
/algorithms/sorting/counting_sort/counting_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func countingSort(size, max int) []int {
9 | count := make([]int, max)
10 | sorted := make([]int, size)
11 | for i := 0; i < size; i++ {
12 | count[arr[i]]++
13 | }
14 | for i := 1; i < max; i++ {
15 | count[i] += count[i-1]
16 | }
17 | for i := size - 1; i >= 0; i-- {
18 | sorted[count[arr[i]]-1] = arr[i]
19 | count[arr[i]]--
20 | }
21 | return sorted
22 | }
23 |
24 | var arr []int
25 |
26 | func main() {
27 | var size, element, min, max int
28 | fmt.Println("\n-- Counting Sort --")
29 | fmt.Print("\nEnter the size of an array: ")
30 | fmt.Scanf("%d\n", &size)
31 | fmt.Println("Start entering elements:")
32 | for i := 0; i < size; i++ {
33 | fmt.Scanf("%d\n", &element)
34 |
35 | if i == 0 {
36 | min = element
37 | max = element
38 | }
39 |
40 | min = int(math.Min(float64(min), float64(element)))
41 | max = int(math.Max(float64(max), float64(element)))
42 | arr = append(arr, element)
43 | }
44 | sorted := countingSort(size, max+1)
45 | fmt.Println("Sorted array is:")
46 | fmt.Println(sorted)
47 | }
48 |
--------------------------------------------------------------------------------
/algorithms/sorting/heap_sort/heap_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func maxHeapify() {
9 | idx := len(arr) - 1
10 | element := arr[idx]
11 | for idx > 0 {
12 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
13 | parent := arr[parentIdx]
14 | if element <= parent {
15 | break
16 | }
17 | arr[parentIdx] = element
18 | arr[idx] = parent
19 | idx = parentIdx
20 | }
21 | }
22 |
23 | // ExtractMax will remove a node from heap
24 | func ExtractMax() int {
25 | if len(arr) == 0 || arr[0] == 0 {
26 | fmt.Println("\n-- Heap is empty. --")
27 | return 0
28 | }
29 | max := arr[0]
30 | end := arr[len(arr)-1]
31 | arr = arr[0 : len(arr)-1]
32 | if len(arr) > 0 {
33 | arr[0] = end
34 | bubbleDown()
35 | }
36 | return max
37 | }
38 |
39 | func bubbleDown() {
40 | idx := 0
41 | length := len(arr)
42 | element := arr[0]
43 | for {
44 | leftChildIdx := (2 * idx) + 1
45 | rightChildIdx := (2 * idx) + 2
46 | var leftChild, rightChild, swap int
47 |
48 | if leftChildIdx < length {
49 | leftChild = arr[leftChildIdx]
50 | if leftChild > element {
51 | swap = leftChildIdx
52 | }
53 | }
54 | if rightChildIdx < length {
55 | rightChild = arr[rightChildIdx]
56 | if (rightChild > element && swap == 0) || (rightChild > leftChild && swap != 0) {
57 | swap = rightChildIdx
58 | }
59 | }
60 |
61 | if swap == 0 {
62 | break
63 | }
64 | arr[idx] = arr[swap]
65 | arr[swap] = element
66 | idx = swap
67 | }
68 | }
69 |
70 | // HeapSort sorts the arr using heap sort technique and returns the sorted arr
71 | func HeapSort(size int) []int {
72 | sorted := make([]int, size)
73 | for i := 0; i < size; i++ {
74 | max := ExtractMax()
75 | sorted[size-1-i] = max
76 | }
77 | return sorted
78 | }
79 |
80 | var arr []int
81 |
82 | func main() {
83 | var size, element int
84 | fmt.Println("\n-- Heap Sort --")
85 | fmt.Print("\nEnter the size of an array: ")
86 | fmt.Scanf("%d\n", &size)
87 | fmt.Println("Start entering elements:")
88 |
89 | for i := 0; i < size; i++ {
90 | fmt.Scanf("%d\n", &element)
91 | arr = append(arr, element)
92 | maxHeapify()
93 | }
94 |
95 | sorted := HeapSort(size)
96 | fmt.Println("Sorted array is:")
97 | fmt.Println(sorted)
98 | }
99 |
--------------------------------------------------------------------------------
/algorithms/sorting/insertion_sort/insertion_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | var size int
9 | var element int
10 | fmt.Println("\n-- Insertion Sort --")
11 | fmt.Print("\nEnter the size of an array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering the elements:")
14 | for i := 0; i < size; i++ {
15 | fmt.Scanf("%d\n", &element)
16 | arr = append(arr, element)
17 | }
18 |
19 | for i := 0; i < size-1; i++ {
20 | j := i
21 | key := arr[i+1]
22 | for j >= 0 && key < arr[j] {
23 | arr[j+1] = arr[j]
24 | j--
25 | }
26 | arr[j+1] = key
27 | }
28 |
29 | fmt.Println("Sorted Array is:")
30 | fmt.Println(arr)
31 | }
32 |
--------------------------------------------------------------------------------
/algorithms/sorting/merge_sort/merge_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | var size int
9 | var element int
10 | fmt.Println("\n-- Merge Sort --")
11 | fmt.Print("\nEnter the size of an array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering elements:")
14 | for i := 0; i < size; i++ {
15 | fmt.Scanf("%d\n", &element)
16 | arr = append(arr, element)
17 | }
18 | mergeSort(0, size-1)
19 | fmt.Println("Sorted Array is:")
20 | fmt.Println(arr)
21 | }
22 |
23 | func merge(l, m, r int) {
24 | var i, j, k int
25 | nl := m - l + 1
26 | nr := r - m
27 | var left, right []int
28 |
29 | for i = 0; i < nl; i++ {
30 | left = append(left, arr[l+i])
31 | }
32 |
33 | for j = 0; j < nr; j++ {
34 | right = append(right, arr[m+1+j])
35 | }
36 |
37 | i = 0
38 | j = 0
39 | k = l
40 |
41 | for i < nl && j < nr {
42 | if left[i] <= right[j] {
43 | arr[k] = left[i]
44 | i++
45 | k++
46 | } else {
47 | arr[k] = right[j]
48 | j++
49 | k++
50 | }
51 | }
52 |
53 | for i < nl {
54 | arr[k] = left[i]
55 | i++
56 | k++
57 | }
58 | for j < nr {
59 | arr[k] = right[j]
60 | j++
61 | k++
62 | }
63 | }
64 |
65 | func mergeSort(l, r int) {
66 | var mid int
67 | if l < r {
68 | mid = (l + r) / 2
69 | mergeSort(l, mid)
70 | mergeSort(mid+1, r)
71 | merge(l, mid, r)
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/algorithms/sorting/quick_sort/quick_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | var size int
9 | var element int
10 | fmt.Println("\n-- Quick Sort --")
11 | fmt.Print("\nEnter the size of an array: ")
12 | fmt.Scanf("%d\n", &size)
13 | fmt.Println("Start entering elements:")
14 | for i := 0; i < size; i++ {
15 | fmt.Scanf("%d\n", &element)
16 | arr = append(arr, element)
17 | }
18 |
19 | quicksort(0, size-1)
20 |
21 | fmt.Println("Sorted Array is:")
22 | fmt.Println(arr)
23 | }
24 |
25 | func partition(first, last int) int {
26 | pivot := arr[first]
27 | i := first
28 | j := last + 1
29 |
30 | for i < j {
31 | i++
32 | j--
33 | for arr[i] < pivot && i < last {
34 | i++
35 | }
36 | for arr[j] > pivot && j > first {
37 | j--
38 | }
39 | if i < j {
40 | arr[i], arr[j] = arr[j], arr[i]
41 | }
42 | }
43 | arr[j], arr[first] = arr[first], arr[j]
44 | return j
45 | }
46 |
47 | func quicksort(first, last int) {
48 | var sp int
49 | if first < last {
50 | sp = partition(first, last)
51 | quicksort(first, sp-1)
52 | quicksort(sp+1, last)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/algorithms/sorting/radix_sort/radix_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | var arr []int
9 |
10 | func main() {
11 | var size int
12 | var element int
13 | fmt.Println("\n-- Radix Sort --")
14 | fmt.Print("\nEnter the size of an array: ")
15 | fmt.Scanf("%d\n", &size)
16 | fmt.Println("Start entering elements:")
17 | for i := 0; i < size; i++ {
18 | fmt.Scanf("%d\n", &element)
19 | arr = append(arr, element)
20 | }
21 | radixSort()
22 | fmt.Println("Sorted Array is:")
23 | fmt.Println(arr)
24 | }
25 |
26 | func radixSort() {
27 | maxDigitCount := mostDigits(arr)
28 |
29 | for k := 0; k < maxDigitCount; k++ {
30 | var bucket [10][]int
31 | for i := 0; i < len(arr); i++ {
32 | digit := getDigit(arr[i], k)
33 | bucket[digit] = append(bucket[digit], arr[i])
34 | }
35 |
36 | // concat numbers back to original array
37 | arr = arr[0:0]
38 | for j := 0; j < 10; j++ {
39 | arr = append(arr, bucket[j]...)
40 | }
41 | }
42 | }
43 |
44 | // getDigit returns an integer whose value is equivalent to index position in given number
45 | func getDigit(value, index int) int {
46 | return int(math.Floor(math.Abs(float64(value)/math.Pow(float64(10), float64(index))))) % 10
47 | }
48 |
49 | // digitCount returns an integer which is the count of number of digits in a given number
50 | func digitCount(value int) int {
51 | if value == 0 {
52 | return 1
53 | }
54 | return int(math.Floor(math.Log10(float64(value)))) + 1
55 | }
56 |
57 | // mostDigits returns a digits count whose length is maximum or say whose value is maximum
58 | func mostDigits(nums []int) int {
59 | maxDigits := 0
60 | for i := 0; i < len(nums); i++ {
61 | maxDigits = int(math.Max(float64(maxDigits), float64(digitCount(nums[i]))))
62 | }
63 | return maxDigits
64 | }
65 |
--------------------------------------------------------------------------------
/algorithms/sorting/selection_sort/selection_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var arr []int
6 |
7 | func main() {
8 | var length int
9 | var element int
10 | fmt.Println("\n-- Selection Sort --")
11 | fmt.Print("\nEnter the size of an array: ")
12 | fmt.Scanf("%d\n", &length)
13 | fmt.Println("Start entering the elements: ")
14 | for i := 0; i < length; i++ {
15 | fmt.Scanf("%d\n", &element)
16 | arr = append(arr, element)
17 | }
18 |
19 | // Sorting
20 | for i := 0; i < length; i++ {
21 | for j := i + 1; j < length; j++ {
22 | if arr[i] > arr[j] {
23 | arr[i], arr[j] = arr[j], arr[i]
24 | }
25 | }
26 | }
27 |
28 | fmt.Println("Sorted Array is:")
29 | fmt.Println(arr)
30 | }
31 |
--------------------------------------------------------------------------------
/algorithms/sorting/shell_sort/shell_sort.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | func shellSort(size int) {
9 | gap := int(math.Floor(float64(size / 2)))
10 | for {
11 | for i := 0; i < size-((size-1)%gap); i++ {
12 |
13 | // swap the elements
14 | if arr[i] > arr[gap+i] {
15 | arr[i], arr[gap+i] = arr[gap+i], arr[i]
16 |
17 | j := i
18 | // start comparing with previous elements
19 | for {
20 | // swap the elements
21 | if j-gap >= 0 && arr[j-gap] > arr[j] {
22 | arr[j-gap], arr[j] = arr[j], arr[j-gap]
23 | j--
24 | } else {
25 | break
26 | }
27 | }
28 | }
29 |
30 | // check whether to break the loop
31 | if i == (size-1)-gap {
32 | break
33 | }
34 | }
35 |
36 | gap = int(math.Floor(float64(gap / 2))) // update the gap
37 |
38 | // break the main loop when gap is 0
39 | if gap == 0 {
40 | break
41 | }
42 | }
43 | }
44 |
45 | var arr []int
46 |
47 | func main() {
48 | var size, element int
49 | fmt.Println("\n-- Shell Sort --")
50 | fmt.Print("\nEnter the size of an array: ")
51 | fmt.Scanf("%d\n", &size)
52 | fmt.Println("Start entering elements:")
53 | for i := 0; i < size; i++ {
54 | fmt.Scanf("%d\n", &element)
55 | arr = append(arr, element)
56 | }
57 | shellSort(size)
58 | fmt.Println("Sorted array is:")
59 | fmt.Println(arr)
60 | }
61 |
--------------------------------------------------------------------------------
/algorithms/string_matching/horspool/horspool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | func main() {
9 | fmt.Println("\n-- Boyer Moore Horspool Algorithm --")
10 |
11 | var text, pattern string
12 |
13 | fmt.Print("\nEnter the text string: ")
14 | fmt.Scanf("%s\n", &text)
15 | fmt.Print("Enter the pattern string: ")
16 | fmt.Scanf("%s\n", &pattern)
17 |
18 | st := ShiftTable(strings.Split(pattern, ""))
19 | fmt.Println(st)
20 | index := Search(strings.Split(text, ""), strings.Split(pattern, ""), st)
21 |
22 | if len(index) == 0 {
23 | fmt.Println("\n-- Pattern not found in text! --")
24 | } else {
25 | fmt.Println("\nPattern found at index/ices:")
26 | fmt.Println(index)
27 | }
28 |
29 | }
30 |
31 | // ShiftTable creates shift table for given pattern
32 | func ShiftTable(pt []string) map[string]int {
33 | st := make(map[string]int)
34 | n := len(pt)
35 | for i := 0; i < n-1; i++ {
36 | if i == n-1 {
37 | if st[pt[i]] == 0 {
38 | st[pt[i]] = n
39 | continue
40 | }
41 | continue
42 | }
43 | st[pt[i]] = n - 1 - i
44 | }
45 |
46 | return st
47 | }
48 |
49 | // Search searches for pattern string in given text string and returns the indices values if pattern is found
50 | // else returns empty array
51 | func Search(txt, pt []string, st map[string]int) []int {
52 |
53 | pos := make([]int, 0)
54 |
55 | var j int
56 | for i := len(pt) - 1; i >= 0 && i < len(txt); {
57 | skip := 0
58 |
59 | for j = len(pt) - 1; j >= 0 && pt[j] == txt[i]; j-- {
60 | i--
61 | if j == 0 {
62 | pos = append(pos, i+2)
63 | i += len(pt) + 1
64 | skip = 1
65 | break
66 | }
67 | }
68 |
69 | if skip == 1 {
70 | continue
71 | }
72 |
73 | stVal := st[txt[i]]
74 |
75 | if stVal == 0 {
76 | stVal = len(pt) - 1
77 | }
78 |
79 | i += stVal
80 | }
81 |
82 | return pos
83 | }
84 |
85 | // Sample test strings
86 | //
87 | // GCAATGCCTATGTGACC
88 | // TATGTG
89 | // 9
90 | //
91 | // AABAACAADAABAABA
92 | // AABA
93 | // [1 10 13]
94 | //
95 | // TRUSTHARDTOOTHBRUSHES
96 | // TOOTH
97 | // 10
98 | //
99 | // GCATATGTGATGCCTATGTGACCTATGTG
100 | // TATGTG
101 | // [4 15 24]
102 | //
103 | // JIM SAW ME IN A BARBER SHOP
104 | // BARBER
105 | // [7]
106 | //
107 | // JIMBARBER SAW ME IN A BARBER SHOP
108 | // BARBER
109 | // [4 23]
110 |
--------------------------------------------------------------------------------
/algorithms/string_matching/knuth_morris_pratt/knuth_morris_pratt.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Knp implements Knuth Morris Pratt Algorithms
6 | func Knp() {
7 | computePi()
8 | i := 0
9 | j := 0
10 | m := len(pattern)
11 | n := len(text)
12 | for i < n {
13 | if pattern[j] == text[i] {
14 | i++
15 | j++
16 | }
17 | if j == m {
18 | fmt.Println("Pattern found at", i-j)
19 | j = pi[j-1]
20 | } else if i < n && pattern[j] != text[i] {
21 | if j != 0 {
22 | j = pi[j-1]
23 | } else {
24 | i++
25 | }
26 | }
27 | }
28 | }
29 |
30 | var text string
31 | var pattern string
32 | var pi []int
33 |
34 | func main() {
35 | fmt.Println("\n-- Knuth Morris Pratt Algorithm --")
36 | fmt.Print("\nEnter the initial text: ")
37 | fmt.Scanf("%s\n", &text)
38 | fmt.Print("Enter the pattern: ")
39 | fmt.Scanf("%s\n", &pattern)
40 | Knp()
41 | }
42 |
43 | func computePi() {
44 | pi = make([]int, len(pattern))
45 | pi[0] = 0
46 | k := 0
47 | for i := 1; i < len(pattern); i++ {
48 | if pattern[i] == pattern[k] {
49 | k++
50 | pi[i] = k
51 | } else {
52 | if k != 0 {
53 | k = pi[k-1]
54 | } else {
55 | pi[i] = k
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/algorithms/string_matching/naive_pattern_matching/naive_pattern_matching.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func naiveMatch() []int {
6 | var occurance []int
7 | for i := range mainString {
8 | for j := range pattern {
9 | if mainString[i+j] != pattern[j] {
10 | break
11 | } else if j == (len(pattern) - 1) {
12 | occurance = append(occurance, i+1)
13 | }
14 | }
15 | }
16 | return occurance
17 | }
18 |
19 | var mainString, pattern string
20 |
21 | func main() {
22 | fmt.Println("\n-- Naive Pattern Matching --")
23 | fmt.Print("\nEnter the main string: ")
24 | fmt.Scanf("%s\n", &mainString)
25 | fmt.Print("Enter the pattern: ")
26 | fmt.Scanf("%s\n", &pattern)
27 | occurance := naiveMatch()
28 | if len(occurance) == 0 {
29 | fmt.Println("-- No pattern found --")
30 | } else {
31 | for i := range occurance {
32 | fmt.Println("Pattern found at index", occurance[i])
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/algorithms/string_matching/rabin_karp/rabin_karp.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "hash/fnv"
6 | )
7 |
8 | func main() {
9 | fmt.Println("-- Rabin Karp --")
10 | var text, pattern string
11 | fmt.Print("Enter the text string: ")
12 | fmt.Scanf("%s\n", &text)
13 | fmt.Print("Enter the pattern string: ")
14 | fmt.Scanf("%s\n", &pattern)
15 | arr := RabinKarpWithoutHash(text, pattern)
16 | fmt.Println("Without using hash function, pattern found at index/ices:", arr)
17 | arr = RabinKarpWithHash(text, pattern)
18 | fmt.Println("With using hash function, pattern found at index/ices:", arr)
19 | }
20 |
21 | // RabinKarpWithoutHash searches for pattern in a given text string without using language built-in hash function
22 | func RabinKarpWithoutHash(text, pattern string) []int {
23 | arr := make([]int, 0)
24 | d := 256
25 | q := 101
26 | m := len(pattern)
27 | n := len(text)
28 | p := 0
29 | t := 0
30 | h := 1
31 | i := 0
32 | j := 0
33 |
34 | for i = 0; i < m-1; i++ {
35 | h = (h * d) % q
36 | }
37 |
38 | for i = 0; i < m; i++ {
39 | p = ((d * p) + int(pattern[i])) % q
40 | t = ((d * t) + int(text[i])) % q
41 | }
42 |
43 | for i = 0; i <= n-m; i++ {
44 | if p == t {
45 | for j = 0; j < m; j++ {
46 | if text[i+j] != pattern[j] {
47 | break
48 | }
49 | }
50 | if j == m {
51 | arr = append(arr, i+1)
52 | }
53 | }
54 |
55 | if i < n-m {
56 | t = ((d * (t - int(text[i])*h)) + (int(text[i+m]))) % q
57 | if t < 0 {
58 | t += q
59 | }
60 | }
61 |
62 | }
63 |
64 | return arr
65 | }
66 |
67 | // RabinKarpWithHash searches for pattern in a given text string by using language built-in hash function
68 | func RabinKarpWithHash(text, pattern string) []int {
69 | arr := make([]int, 0)
70 | m := len(pattern)
71 | n := len(text)
72 | p := ""
73 | t := ""
74 | i := 0
75 | j := 0
76 |
77 | p = hash(pattern[0:m])
78 | t = hash(text[0:m])
79 |
80 | for i = 0; i <= n-m; i++ {
81 | if p == t {
82 | for j = 0; j < m; j++ {
83 | if text[i+j] != pattern[j] {
84 | break
85 | }
86 | }
87 | if j == m {
88 | arr = append(arr, i+1)
89 | }
90 | }
91 |
92 | if i < n-m {
93 | t = hash(text[i : i+m+1])
94 | }
95 |
96 | }
97 |
98 | return arr
99 | }
100 |
101 | func hash(s string) string {
102 | h := fnv.New32a()
103 | h.Write([]byte(s))
104 | return string(h.Sum32())
105 | }
106 |
--------------------------------------------------------------------------------
/algorithms/toh/toh.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var n int
7 | fmt.Println("\n-- Tower of Hanoi --")
8 | fmt.Print("\nEnter the number of discs: ")
9 | fmt.Scanf("%d\n", &n)
10 | Toh("A", "B", "C", n)
11 | }
12 |
13 | // Toh recursively calls iteself to implment tower of hanoi algorithm
14 | func Toh(origin, intermediate, destination string, n int) {
15 | if n == 1 {
16 | fmt.Println("Move disc", n, "from", origin, "->", destination)
17 | return
18 | }
19 | Toh(origin, destination, intermediate, n-1)
20 | fmt.Println("Move disc", n, "from", origin, "->", destination)
21 | Toh(intermediate, origin, destination, n-1)
22 | }
23 |
--------------------------------------------------------------------------------
/graphs/directed_unweighted/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // DFS traverses a graph using dfs technique
6 | func (g graph) DFS() []string {
7 | visited := make(map[string]bool)
8 | var result []string
9 | if len(g) == 0 {
10 | fmt.Println("\n-- Graph is empty. --")
11 | return nil
12 | }
13 | for i := range g {
14 | if !visited[i] {
15 | result = g.dfsHelper(i, visited, result)
16 | }
17 | }
18 | return result
19 | }
20 |
21 | // dfsHelper recursively calls itself to solve dfs traversal
22 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string) []string {
23 | visited[vtx] = true
24 | result = append(result, vtx)
25 | for i := range g[vtx] {
26 | if !visited[g[vtx][i]] {
27 | result = g.dfsHelper(g[vtx][i], visited, result)
28 | }
29 | }
30 | return result
31 | }
32 |
33 | // BFS traverses a graph using dfs technique
34 | func (g graph) BFS() []string {
35 |
36 | if len(g) == 0 {
37 | fmt.Println("\n-- Graph is empty. --")
38 | return nil
39 | }
40 |
41 | visited := make(map[string]bool)
42 |
43 | var queue []string
44 | var result []string
45 | var currentVtx string
46 |
47 | for i := range g {
48 | if !visited[i] {
49 | visited[i] = true
50 | queue = append(queue, i)
51 |
52 | for len(queue) != 0 {
53 | currentVtx = queue[0] // get the element from the queue
54 | queue = queue[1:] // remove element from the queue
55 | result = append(result, currentVtx) // push the current vertex in result
56 |
57 | for j := range g[currentVtx] {
58 | if !visited[g[currentVtx][j]] {
59 | visited[g[currentVtx][j]] = true // mark as visited
60 | queue = append(queue, g[currentVtx][j]) // push neighbors of current vertex in the queue
61 | }
62 | }
63 |
64 | }
65 |
66 | }
67 | }
68 |
69 | return result
70 | }
71 |
--------------------------------------------------------------------------------
/graphs/directed_weighted/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // DFS traverses a graph using dfs technique
6 | func (g graph) DFS() ([]string, []int) {
7 | visited := make(map[string]bool)
8 |
9 | var result []string
10 | var weights []int
11 |
12 | if len(g) == 0 {
13 | fmt.Println("\n-- Graph is empty. --")
14 | return nil, nil
15 | }
16 | for i := range g {
17 | if !visited[i] {
18 | result, weights = g.dfsHelper(i, visited, result, weights)
19 | }
20 | }
21 | return result, weights
22 | }
23 |
24 | // dfsHelper recursively calls itself to solve dfs traversal
25 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string, weights []int) ([]string, []int) {
26 | visited[vtx] = true
27 | result = append(result, vtx)
28 | for i := range g[vtx] {
29 | if !visited[g[vtx][i].name] {
30 | weights = append(weights, g[vtx][i].value)
31 | result, weights = g.dfsHelper(g[vtx][i].name, visited, result, weights)
32 | }
33 | }
34 | return result, weights
35 | }
36 |
37 | // BFS traverses a graph using dfs technique
38 | func (g graph) BFS() ([]string, []int) {
39 |
40 | if len(g) == 0 {
41 | fmt.Println("\n-- Graph is empty. --")
42 | return nil, nil
43 | }
44 |
45 | visited := make(map[string]bool)
46 | var queue []string
47 | var result []string
48 | var currentVtx string
49 | var weights []int
50 |
51 | for i := range g {
52 | if !visited[i] {
53 | visited[i] = true
54 | queue = append(queue, i)
55 |
56 | for len(queue) != 0 {
57 | currentVtx = queue[0] // get the element from the queue
58 | queue = queue[1:] // remove element from the queue
59 | result = append(result, currentVtx) // push the current vertex in result
60 |
61 | for j := range g[currentVtx] {
62 | if !visited[g[currentVtx][j].name] {
63 | visited[g[currentVtx][j].name] = true // mark as visited
64 | weights = append(weights, g[currentVtx][j].value)
65 | queue = append(queue, g[currentVtx][j].name) // push neighbors of current vertex in the queue
66 | }
67 | }
68 |
69 | }
70 | }
71 | }
72 |
73 | return result, weights
74 | }
75 |
--------------------------------------------------------------------------------
/graphs/undirected_unweighted/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // DFS traverses a graph using dfs technique
6 | func (g graph) DFS(start string) []string {
7 | visited := make(map[string]bool)
8 | var result []string
9 | if g[start] == nil {
10 | fmt.Println("\n-- No vertex named " + start + " present in graph. --")
11 | return nil
12 | }
13 | result = g.dfsHelper(start, visited, result)
14 | return result
15 | }
16 |
17 | // dfsHelper recursively calls itself to solve dfs traversal
18 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string) []string {
19 | visited[vtx] = true
20 | result = append(result, vtx)
21 | for i := range g[vtx] {
22 | if !visited[g[vtx][i]] {
23 | result = g.dfsHelper(g[vtx][i], visited, result)
24 | }
25 | }
26 | return result
27 | }
28 |
29 | // BFS traverses a graph using dfs technique
30 | func (g graph) BFS(start string) []string {
31 |
32 | if g[start] == nil {
33 | fmt.Println("\n-- No vertex named " + start + " present in graph. --")
34 | return nil
35 | }
36 |
37 | visited := make(map[string]bool)
38 |
39 | var queue []string
40 | queue = append(queue, start)
41 |
42 | var result []string
43 | var currentVtx string
44 | visited[start] = true
45 |
46 | for len(queue) != 0 {
47 | currentVtx = queue[0] // get the element from the queue
48 | queue = queue[1:] // remove element from the queue
49 | result = append(result, currentVtx) // push the current vertex in result
50 |
51 | for i := range g[currentVtx] {
52 | if !visited[g[currentVtx][i]] {
53 | visited[g[currentVtx][i]] = true // mark as visited
54 | queue = append(queue, g[currentVtx][i]) // push neighbors of current vertex in the queue
55 | }
56 | }
57 |
58 | }
59 |
60 | return result
61 | }
62 |
--------------------------------------------------------------------------------
/graphs/undirected_weighted/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // DFS traverses a graph using dfs technique
6 | func (g graph) DFS(start string) ([]string, []int) {
7 | visited := make(map[string]bool)
8 | var result []string
9 | var weights []int
10 | if g[start] == nil {
11 | fmt.Println("\n-- No vertex named " + start + " present in graph. --")
12 | return nil, nil
13 | }
14 | result, weights = g.dfsHelper(start, visited, result, weights)
15 | return result, weights
16 | }
17 |
18 | // dfsHelper recursively calls itself to solve dfs traversal
19 | func (g graph) dfsHelper(vtx string, visited map[string]bool, result []string, weights []int) ([]string, []int) {
20 | visited[vtx] = true
21 | result = append(result, vtx)
22 | for i := range g[vtx] {
23 | if !visited[g[vtx][i].name] {
24 | weights = append(weights, g[vtx][i].value)
25 | result, weights = g.dfsHelper(g[vtx][i].name, visited, result, weights)
26 | }
27 | }
28 | return result, weights
29 | }
30 |
31 | // BFS traverses a graph using dfs technique
32 | func (g graph) BFS(start string) ([]string, []int) {
33 |
34 | if g[start] == nil {
35 | fmt.Println("\n-- No vertex named " + start + " present in graph. --")
36 | return nil, nil
37 | }
38 |
39 | visited := make(map[string]bool)
40 |
41 | var queue []string
42 | queue = append(queue, start)
43 |
44 | var result []string
45 | var weights []int
46 | var currentVtx string
47 | visited[start] = true
48 |
49 | for len(queue) != 0 {
50 | currentVtx = queue[0] // get the element from the queue
51 | queue = queue[1:] // remove element from the queue
52 | result = append(result, currentVtx) // push the current vertex in result
53 |
54 | for i := range g[currentVtx] {
55 | if !visited[g[currentVtx][i].name] {
56 | visited[g[currentVtx][i].name] = true // mark as visited
57 | weights = append(weights, g[currentVtx][i].value)
58 | queue = append(queue, g[currentVtx][i].name) // push neighbors of current vertex in the queue
59 | }
60 | }
61 |
62 | }
63 |
64 | return result, weights
65 | }
66 |
--------------------------------------------------------------------------------
/heaps/max_binary_heap/max_binary_heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // Insert inserts a node in a heap
9 | func Insert(value int) {
10 | heap = append(heap, value)
11 | maxHeapify()
12 | }
13 |
14 | func maxHeapify() {
15 | idx := len(heap) - 1
16 | element := heap[idx]
17 | for idx > 0 {
18 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
19 | parent := heap[parentIdx]
20 | if element <= parent {
21 | break
22 | }
23 | heap[parentIdx] = element
24 | heap[idx] = parent
25 | idx = parentIdx
26 | }
27 | }
28 |
29 | // ExtractMax will remove a node from heap
30 | func ExtractMax() int {
31 | if len(heap) == 0 || heap[0] == 0 {
32 | fmt.Println("\n-- Heap is empty. --")
33 | return 0
34 | }
35 | max := heap[0]
36 | end := heap[len(heap)-1]
37 | heap = heap[0 : len(heap)-1]
38 | if len(heap) > 0 {
39 | heap[0] = end
40 | bubbleDown()
41 | }
42 | return max
43 | }
44 |
45 | func bubbleDown() {
46 | idx := 0
47 | length := len(heap)
48 | element := heap[0]
49 | for {
50 | leftChildIdx := (2 * idx) + 1
51 | rightChildIdx := (2 * idx) + 2
52 | var leftChild, rightChild, swap int
53 |
54 | if leftChildIdx < length {
55 | leftChild = heap[leftChildIdx]
56 | if leftChild > element {
57 | swap = leftChildIdx
58 | }
59 | }
60 | if rightChildIdx < length {
61 | rightChild = heap[rightChildIdx]
62 | if (rightChild > element && swap == 0) || (rightChild > leftChild && swap != 0) {
63 | swap = rightChildIdx
64 | }
65 | }
66 |
67 | if swap == 0 {
68 | break
69 | }
70 | heap[idx] = heap[swap]
71 | heap[swap] = element
72 | idx = swap
73 | }
74 | }
75 |
76 | var heap []int
77 |
78 | func main() {
79 | i := 0
80 | for i == 0 {
81 | fmt.Println("\n1. INSERT")
82 | fmt.Println("2. REMOVE")
83 | fmt.Println("3. DISPLAY")
84 | fmt.Println("4. EXIT")
85 | var ch int
86 | fmt.Print("Enter your choice: ")
87 | fmt.Scanf("%d\n", &ch)
88 | switch ch {
89 | case 1:
90 | insertNode()
91 | case 2:
92 | ExtractMax()
93 | case 3:
94 | display()
95 | case 4:
96 | i = 1
97 | default:
98 | fmt.Println("Command not recognized.")
99 | }
100 | }
101 | }
102 |
103 | func insertNode() {
104 | var ch int
105 | fmt.Print("Enter the element that you want to insert: ")
106 | fmt.Scanf("%d\n", &ch)
107 | Insert(ch)
108 | }
109 |
110 | func display() {
111 | fmt.Println("")
112 | fmt.Println(heap)
113 | }
114 |
--------------------------------------------------------------------------------
/heaps/min_binary_heap/min_binary_heap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // Insert inserts a node in a heap
9 | func Insert(value int) {
10 | heap = append(heap, value)
11 | minHeapify()
12 | }
13 |
14 | func minHeapify() {
15 | idx := len(heap) - 1
16 | element := heap[idx]
17 | for idx > 0 {
18 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
19 | parent := heap[parentIdx]
20 | if element >= parent {
21 | break
22 | }
23 | heap[parentIdx] = element
24 | heap[idx] = parent
25 | idx = parentIdx
26 | }
27 | }
28 |
29 | // ExtractMin will remove a node from heap
30 | func ExtractMin() int {
31 | if len(heap) == 0 || heap[0] == 0 {
32 | fmt.Println("\n-- Heap is empty. --")
33 | return 0
34 | }
35 | min := heap[0]
36 | end := heap[len(heap)-1]
37 | heap = heap[0 : len(heap)-1]
38 | if len(heap) > 0 {
39 | heap[0] = end
40 | bubbleDown()
41 | }
42 | return min
43 | }
44 |
45 | func bubbleDown() {
46 | idx := 0
47 | length := len(heap)
48 | element := heap[0]
49 | for {
50 | leftChildIdx := (2 * idx) + 1
51 | rightChildIdx := (2 * idx) + 2
52 | var leftChild, rightChild, swap int
53 |
54 | if leftChildIdx < length {
55 | leftChild = heap[leftChildIdx]
56 | if leftChild < element {
57 | swap = leftChildIdx
58 | }
59 | }
60 | if rightChildIdx < length {
61 | rightChild = heap[rightChildIdx]
62 | if (rightChild < element && swap == 0) || (rightChild < leftChild && swap != 0) {
63 | swap = rightChildIdx
64 | }
65 | }
66 |
67 | if swap == 0 {
68 | break
69 | }
70 | heap[idx] = heap[swap]
71 | heap[swap] = element
72 | idx = swap
73 | }
74 | }
75 |
76 | var heap []int
77 |
78 | func main() {
79 | i := 0
80 | for i == 0 {
81 | fmt.Println("\n1. INSERT")
82 | fmt.Println("2. REMOVE")
83 | fmt.Println("3. DISPLAY")
84 | fmt.Println("4. EXIT")
85 | var ch int
86 | fmt.Print("Enter your choice: ")
87 | fmt.Scanf("%d\n", &ch)
88 | switch ch {
89 | case 1:
90 | insertNode()
91 | case 2:
92 | ExtractMin()
93 | case 3:
94 | display()
95 | case 4:
96 | i = 1
97 | default:
98 | fmt.Println("Command not recognized.")
99 | }
100 | }
101 | }
102 |
103 | func insertNode() {
104 | var ch int
105 | fmt.Print("Enter the element that you want to insert: ")
106 | fmt.Scanf("%d\n", &ch)
107 | Insert(ch)
108 | }
109 |
110 | func display() {
111 | fmt.Println("")
112 | fmt.Println(heap)
113 | }
114 |
--------------------------------------------------------------------------------
/linked_lists/pres_rev_single_ll/RGIF2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deveshptl/golang-data-structures-algorithms/8522c89d4e6ae1aa273754f1507cb75706784f6a/linked_lists/pres_rev_single_ll/RGIF2.gif
--------------------------------------------------------------------------------
/notes/heaps/README.md:
--------------------------------------------------------------------------------
1 | # Heap
2 |
3 | Heap is a tree based data structure where the tree is a complete binary tree. This binary tree satisfies the properties of heap:
4 |
5 | 1. For max heap, any given node C, if P is a parent node of C, then the key (the value) of P is greater than or equal to the key of C.
6 | 2. For min heap, any given node C, if P is a parent node of C, then the key (the value) of P is less than or equal to the key of C.
7 |
8 | ### Representation
9 |
10 | Heap can be implemented using binary tree or array.
11 |
12 | ### Types
13 |
14 | 1. Min Binary Heap: Returns the least value node present in the heap.
15 | 2. Max Binary Heaps: Returns the max value node present in the heap.
16 |
17 | ### Operations
18 |
19 | 1. **Insert**: Inserts a node in the heap
20 | 2. **ExtractMin/ExtractMax**: Extracts the min or max value node depending on the type of the heap
21 | 3. **Delete**: Deletes a node from the heap
22 | 4. **Increase/Decrease Key**: Increases or decreases the key value of given node
23 |
24 | Main functions of heap are:
25 |
26 | 1. **MaxHeapify/MinHeapify (aka Bubble Up)**: This is called after inserting an element, which is inserted in the end of the heap. This function traverses the heap in upward direction while making necessary shifts between nodes.
27 | 2. **Bubble down**: This is called after deleting an element, which is the root of the heap and the last node of the heap is placed there instead. This function traverses downward in direction while making necessary shifts between nodes.
28 |
29 | ### Applications
30 |
31 | 1. Heap Sort: Used to sort the elements in an array
32 | 2. Priority Queue: Used to select the highest priority job
33 | 3. Graph Algorithms: Used in graph algorithms like Dijkstra’s Shortest Path and Prim’s Minimum Spanning Tree
34 |
35 | ## References
36 |
37 | - [https://en.wikipedia.org/wiki/Heap\_(data_structure)]()
38 | - [https://en.wikipedia.org/wiki/Binary_heap](https://en.wikipedia.org/wiki/Binary_heap)
39 | - [https://www.geeksforgeeks.org/binary-heap/](https://www.geeksforgeeks.org/binary-heap/)
40 |
--------------------------------------------------------------------------------
/notes/stack/README.md:
--------------------------------------------------------------------------------
1 | ## Stack
2 |
3 | Stack is a linear data structure which follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out).
4 |
5 | ### Operations
6 |
7 | 1. **PUSH** - Adds an item in the stack and increments the `top` pointer. If the stack is full, then it is said to be an Overflow condition.
8 | 2. **POP** - Removes an item from the stack and decrements the `top`. The items are popped in the reversed order in which they are pushed. If the stack is empty, then it is said to be an Underflow condition.
9 | 3. **PEEK** - Returns top element of stack. Does not remove any elements from stack.
10 | 4. **isEmpty** - Returns true if stack is empty, else false.
11 | 5. **DISPLAY** - Displays content of stack.
12 | 6. **getSize** - Returns the size of the stack irrespective of how many elements are in the stack.
13 |
14 | ### Implementation
15 |
16 | Stack can be implemented using arrays, linked list or queues. Implementation using arrays is the simplest one.
17 |
18 | ### Time Complexities
19 |
20 | - push(), pop(), isEmpty() and peek() all take O(1) time. We do not run any loop in any of these operations.
21 |
22 | ### Applications
23 |
24 | 1. Expression evaluation
25 | 2. Expression conversion
26 | 3. Syntax parsing
27 | 4. String reversal
28 | 5. Implementation of Tower of Hanoi Problem
29 | 6. Function call and Recursion
30 | 7. Parenthesis checking
31 | 8. Backtracking
32 | 9. File undo and redo operations
33 | 10. Depth First Search traversal in tree and graph data structure uses stack to store explored nodes and processes them later.
34 |
35 | ## References
36 |
37 | - [https://www.geeksforgeeks.org/stack-data-structure/](https://www.geeksforgeeks.org/stack-data-structure/)
38 | - [https://www.geeksforgeeks.org/stack-data-structure-introduction-program/](https://www.geeksforgeeks.org/stack-data-structure-introduction-program/)
39 | - [https://www.thecrazyprogrammer.com/2016/04/applications-of-stack.html](https://www.thecrazyprogrammer.com/2016/04/applications-of-stack.html)
40 |
--------------------------------------------------------------------------------
/queues/cqueue/cqueue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // r - rear pointer
8 | // f - front pointer
9 | // n - size of circular queue
10 | // q - circular queue
11 |
12 | type queue []string
13 |
14 | var r, n, f int
15 | var q queue
16 |
17 | func init() {
18 | r = -1
19 | f = -1
20 | n = 4
21 | q = make(queue, 5)
22 | for i := range q {
23 | q[i] = "nil"
24 | }
25 | }
26 |
27 | func main() {
28 | i := 0
29 | for i == 0 {
30 | fmt.Println("\n1. INSERT")
31 | fmt.Println("2. DELETE")
32 | fmt.Println("3. DISPLAY")
33 | fmt.Println("4. EXIT")
34 | fmt.Print("Enter your choice: ")
35 | var choice int
36 | fmt.Scanf("%d\n", &choice)
37 | switch choice {
38 | case 1:
39 | q.insert()
40 | fmt.Println("\nValues after insertion - FRONT:", f, "REAR:", r)
41 | display()
42 | case 2:
43 | q.delete()
44 | fmt.Println("\nValues after deletion - FRONT:", f, "REAR:", r)
45 | display()
46 | case 3:
47 | fmt.Println("\nFRONT:", f, "REAR:", r)
48 | display()
49 | case 4:
50 | i = 1
51 | default:
52 | fmt.Println("Command not recognized.")
53 | }
54 | }
55 | }
56 |
57 | func (q queue) insert() {
58 |
59 | // reset rear pointer
60 | if r == n {
61 | r = 0
62 | } else {
63 | r++
64 | }
65 |
66 | // check for overflow
67 | if f == r {
68 | fmt.Println("\n-- Overflow --")
69 | if r == 0 {
70 | r = n
71 | } else {
72 | r--
73 | }
74 | return
75 | }
76 |
77 | // insert element
78 | var y string
79 | fmt.Print("Enter the element that you want to insert: ")
80 | fmt.Scanf("%s\n", &y)
81 | q[r] = y
82 |
83 | // set front pointer
84 | if f == -1 {
85 | f = 0
86 | }
87 | }
88 |
89 | func (q queue) delete() {
90 |
91 | // check for underflow
92 | if f == -1 {
93 | fmt.Println("\n-- Underflow --")
94 | return
95 | }
96 |
97 | // delete the element
98 | y := q[f]
99 | q[f] = "nil"
100 |
101 | // check if queue is empty
102 | if f == r {
103 | f = -1
104 | r = -1
105 | fmt.Println("\nElement deleted: ", y)
106 | return
107 | }
108 |
109 | // increment front pointer
110 | if f == n {
111 | f = 0
112 | } else {
113 | f++
114 | }
115 |
116 | fmt.Println("\nElement deleted: ", y)
117 |
118 | }
119 |
120 | func display() {
121 | fmt.Println("Displaying elements: ")
122 | for i := range q {
123 | fmt.Print(q[i], " ")
124 | }
125 | fmt.Println("")
126 | }
127 |
--------------------------------------------------------------------------------
/queues/priority_queue/priority_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Note - Lower priority value processes will be run first. Hence this is implemented using min heap.
4 |
5 | import (
6 | "fmt"
7 | "math"
8 | )
9 |
10 | // Node is a single node in a queue
11 | type Node struct {
12 | name string
13 | priority int
14 | }
15 |
16 | // Enqueue inserts a node in a heap
17 | func Enqueue(node *Node) {
18 | heap = append(heap, node)
19 | minHeapify()
20 | }
21 |
22 | func minHeapify() {
23 | idx := len(heap) - 1
24 | element := heap[idx]
25 | for idx > 0 {
26 | parentIdx := int(math.Floor(float64((idx - 1) / 2)))
27 | parent := heap[parentIdx]
28 | if element.priority >= parent.priority {
29 | break
30 | }
31 | heap[parentIdx] = element
32 | heap[idx] = parent
33 | idx = parentIdx
34 | }
35 | }
36 |
37 | // Dequeue will remove a node from heap
38 | func Dequeue() *Node {
39 | if len(heap) == 0 || heap[0] == nil {
40 | fmt.Println("\n-- Heap is empty. --")
41 | return nil
42 | }
43 | min := heap[0]
44 | end := heap[len(heap)-1]
45 | heap = heap[0 : len(heap)-1]
46 | if len(heap) > 0 {
47 | heap[0] = end
48 | bubbleDown()
49 | }
50 | return min
51 | }
52 |
53 | func bubbleDown() {
54 | idx := 0
55 | length := len(heap)
56 | element := heap[0]
57 | for {
58 | leftChildIdx := (2 * idx) + 1
59 | rightChildIdx := (2 * idx) + 2
60 | var leftChild, rightChild *Node
61 | var swap int
62 |
63 | if leftChildIdx < length {
64 | leftChild = heap[leftChildIdx]
65 | if leftChild.priority < element.priority {
66 | swap = leftChildIdx
67 | }
68 | }
69 | if rightChildIdx < length {
70 | rightChild = heap[rightChildIdx]
71 | if (rightChild.priority < element.priority && swap == 0) || (rightChild.priority < leftChild.priority && swap != 0) {
72 | swap = rightChildIdx
73 | }
74 | }
75 |
76 | if swap == 0 {
77 | break
78 | }
79 | heap[idx] = heap[swap]
80 | heap[swap] = element
81 | idx = swap
82 | }
83 | }
84 |
85 | var heap []*Node
86 |
87 | func main() {
88 | i := 0
89 | for i == 0 {
90 | fmt.Println("\n1. INSERT")
91 | fmt.Println("2. REMOVE")
92 | fmt.Println("3. DISPLAY")
93 | fmt.Println("4. EXIT")
94 | var ch int
95 | fmt.Print("Enter your choice: ")
96 | fmt.Scanf("%d\n", &ch)
97 | switch ch {
98 | case 1:
99 | insertNode()
100 | case 2:
101 | node := Dequeue()
102 | fmt.Println("Process removed: ", node)
103 | case 3:
104 | display()
105 | case 4:
106 | i = 1
107 | default:
108 | fmt.Println("Command not recognized.")
109 | }
110 | }
111 | }
112 |
113 | func insertNode() {
114 | var name string
115 | var priority int
116 | fmt.Print("Enter the name of the process: ")
117 | fmt.Scanf("%s\n", &name)
118 | fmt.Print("Enter the priority of the process: ")
119 | fmt.Scanf("%d\n", &priority)
120 | fmt.Println(name, priority)
121 | newNode := &Node{name: name, priority: priority}
122 | Enqueue(newNode)
123 | }
124 |
125 | func display() {
126 | if len(heap) == 0 {
127 | fmt.Println("\n-- Heap is empty. --")
128 | return
129 | }
130 | for i := range heap {
131 | fmt.Println(heap[i].name, heap[i].priority)
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/queues/simple_queue/simple_queue.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // r - rear
8 | // n - length
9 | // f - front
10 | // q - queue
11 |
12 | type queue []string
13 |
14 | var r, n, f int
15 | var q queue
16 |
17 | func init() {
18 | r = -1
19 | f = -1
20 | n = 4
21 | q = make(queue, 5)
22 | for i := range q {
23 | q[i] = "nil"
24 | }
25 | }
26 |
27 | func main() {
28 | i := 0
29 | var choice int
30 | for i == 0 {
31 | fmt.Println("\n1. INSERT")
32 | fmt.Println("2. DELETE")
33 | fmt.Println("3. DISPLAY")
34 | fmt.Println("4. EXIT")
35 | fmt.Print("Enter your choice: ")
36 | fmt.Scanf("%d\n", &choice)
37 | switch choice {
38 | case 1:
39 | q.insert()
40 | fmt.Println("\nValues after insertion FRONT:", f, "REAR:", r)
41 | display()
42 | case 2:
43 | q.delete()
44 | fmt.Println("\nValues after deletion FRONT:", f, "REAR:", r)
45 | display()
46 | case 3:
47 | fmt.Println("\nFRONT:", f, "REAR:", r)
48 | display()
49 | case 4:
50 | i = 1
51 | default:
52 | fmt.Println("\nCommand not recognized")
53 | }
54 | }
55 | }
56 |
57 | func (q queue) insert() {
58 |
59 | // check for overflow
60 | if r >= n {
61 | fmt.Println("\n-- Overflow --")
62 | return
63 | }
64 |
65 | // increment rear pointer
66 | r++
67 |
68 | // insert the element
69 | var y string
70 | fmt.Print("Enter the element that you want to insert: ")
71 | fmt.Scanf("%s\n", &y)
72 | q[r] = y
73 |
74 | // set front pointer
75 | if f == -1 {
76 | f = 0
77 | }
78 | }
79 |
80 | func (q queue) delete() {
81 |
82 | // check for underflow
83 | if f == -1 {
84 | fmt.Println("\n-- Underflow --")
85 | return
86 | }
87 |
88 | // delete element
89 | y := q[f]
90 | q[f] = "nil"
91 |
92 | // check if queue is empty
93 | if f == r {
94 | f = -1
95 | r = -1
96 | } else {
97 | f++
98 | }
99 |
100 | // print deleted element
101 | fmt.Println("Element deleted", y)
102 | }
103 |
104 | func display() {
105 | for i := range q {
106 | fmt.Print(q[i], " ")
107 | }
108 | fmt.Println("")
109 | }
110 |
--------------------------------------------------------------------------------
/resources.md:
--------------------------------------------------------------------------------
1 | ### Useful Websites
2 |
3 | The below list contains the list of websites or youtube channels that I referred while I was implementing this data structures and algorithms.
4 |
5 | 1. [William Fiset - youtube channel](https://www.youtube.com/channel/UCD8yeTczadqdARzQUp29PJw)
6 | 2. [Youtube playlist - A list of all DSA videos created so far by William Fiset](https://www.youtube.com/playlist?list=PLDd6ofQIcSMMc1fzkLYFwZT072DB0ZrMS)
7 | 3. [Geeks for Geeks](https://www.geeksforgeeks.org/)
8 | 4. [AVL Tree - Live Youtube Webinar](https://www.youtube.com/watch?v=a96JFhw5Ee4)
9 | 5. [Data Structures that I learnt during my CS degree](http://gtu-info.com/Subject/2130702/DS/Data_Structures/Syllabus)
10 | 6. [Algorithms that I learnt during my CS degree](http://gtu-info.com/Subject/2150703/ADA/Analysis_and_Design_of_Algorithms/Syllabus)
11 | 7. [A book on Introduction to the Design and Analysis of Algorithms](https://amzn.to/2WPFzuW) by Anany Levitin
12 |
13 | The following list contains some helpful links
14 |
15 | 1. [https://github.com/mtdvio/every-programmer-should-know](https://github.com/mtdvio/every-programmer-should-know)
16 | 2. [https://github.com/jwasham/coding-interview-university](https://github.com/jwasham/coding-interview-university)
17 | 3. [https://github.com/trekhleb/javascript-algorithms](https://github.com/trekhleb/javascript-algorithms)
18 |
--------------------------------------------------------------------------------
/stack/stack.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // size - size of stack
6 | // top - top pointer
7 | // stack - stack array
8 |
9 | type stack []string
10 |
11 | var s stack
12 | var size, top int
13 |
14 | func init() {
15 | size = 4
16 | top = -1
17 | s = make(stack, 5)
18 | for i := range s {
19 | s[i] = "nil"
20 | }
21 | }
22 |
23 | func main() {
24 | i := 0
25 | for i == 0 {
26 | var choice int
27 | fmt.Println("\n1. PUSH")
28 | fmt.Println("2. POP")
29 | fmt.Println("3. PEEK")
30 | fmt.Println("4. DISPLAY")
31 | fmt.Println("5. isEmpty")
32 | fmt.Println("6. EXIT")
33 | fmt.Print("\nEnter you choice: ")
34 | fmt.Scanf("%d\n", &choice)
35 |
36 | switch choice {
37 | case 1:
38 | s.push()
39 | fmt.Println("\nValues after push TOP:", top)
40 | s.display()
41 | case 2:
42 | s.pop()
43 | fmt.Println("\nValues after pop TOP:", top)
44 | s.display()
45 | case 3:
46 | s.peek()
47 | fmt.Println("\nValues after peek TOP:", top)
48 | s.display()
49 | case 4:
50 | fmt.Println("\nTOP:", top)
51 | s.display()
52 | case 5:
53 | s.isEmpty()
54 | case 6:
55 | i = 1
56 | default:
57 | fmt.Println("Choice not recognized")
58 | }
59 |
60 | }
61 | }
62 |
63 | func (s stack) push() {
64 |
65 | // check for overflow
66 | if size == top {
67 | fmt.Println("\n-- Stack overflow --")
68 | return
69 | }
70 |
71 | // scan for element
72 | var val string
73 | fmt.Print("Enter the value that you want to PUSH: ")
74 | fmt.Scanf("%s\n", &val)
75 |
76 | // increment top pointer
77 | top++
78 |
79 | // insert the element
80 | s[top] = val
81 | }
82 |
83 | func (s stack) pop() {
84 |
85 | // check for underflow
86 | if top == -1 {
87 | fmt.Println("\n-- Stack underflow --")
88 | return
89 | }
90 |
91 | // print popped value
92 | y := s[top]
93 | fmt.Println("\nValue popped:", y)
94 |
95 | // initialize to nil
96 | s[top] = "nil"
97 |
98 | // decrement top pointer
99 | top--
100 | }
101 |
102 | func (s stack) peek() {
103 | // check for underflow
104 | if top == -1 {
105 | fmt.Println("\n-- Stack underflow --")
106 | return
107 | }
108 |
109 | // print the peeked value
110 | y := s[top]
111 | fmt.Println("\nValue peeked:", y)
112 | }
113 |
114 | func (s stack) isEmpty() {
115 | if top == -1 {
116 | fmt.Println("\ntrue")
117 | return
118 | }
119 | fmt.Println("\nfalse")
120 | }
121 |
122 | func (s stack) display() {
123 | for i := range s {
124 | fmt.Print(s[i], " ")
125 | }
126 | fmt.Println("")
127 | }
128 |
--------------------------------------------------------------------------------
/trees/avl_tree_using_ll/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // BFS prints the tree using bfs traversal
6 | func (avl *AVLTree) BFS() []int {
7 | if avl.root == nil {
8 | fmt.Print("\n-- Tree is empty. --")
9 | return nil
10 | }
11 | var queue []*Node
12 | var data []int
13 | node := avl.root
14 | queue = append(queue, node)
15 |
16 | for len(queue) != 0 {
17 | node = queue[0]
18 | queue = queue[1:]
19 | count := node.freq
20 | for count != 0 {
21 | data = append(data, node.value)
22 | count--
23 | }
24 | if node.left != nil {
25 | queue = append(queue, node.left)
26 | }
27 | if node.right != nil {
28 | queue = append(queue, node.right)
29 | }
30 | }
31 | return data
32 | }
33 |
34 | // DFS prints the tree using dfs traversal
35 | func (avl *AVLTree) DFS(traverseType string) []int {
36 | if avl.root == nil {
37 | fmt.Println("\n-- Tree is empty. --")
38 | return nil
39 | }
40 |
41 | var data []int
42 | current := avl.root
43 | if traverseType == "pre" {
44 | data = traversePre(data, current)
45 | } else if traverseType == "in" {
46 | data = traverseIn(data, current)
47 | } else if traverseType == "pos" {
48 | data = traversePos(data, current)
49 | }
50 | return data
51 | }
52 |
53 | // traverses a node in pre-order and recursively calls itself
54 | func traversePre(data []int, node *Node) []int {
55 | count := node.freq
56 | for count != 0 {
57 | data = append(data, node.value)
58 | count--
59 | }
60 | if node.left != nil {
61 | data = traversePre(data, node.left)
62 | }
63 | if node.right != nil {
64 | data = traversePre(data, node.right)
65 | }
66 | return data
67 | }
68 |
69 | // traverses a node in in-order and recursively calls itself
70 | func traverseIn(data []int, node *Node) []int {
71 | if node.left != nil {
72 | data = traverseIn(data, node.left)
73 | }
74 | count := node.freq
75 | for count != 0 {
76 | data = append(data, node.value)
77 | count--
78 | }
79 | if node.right != nil {
80 | data = traverseIn(data, node.right)
81 | }
82 | return data
83 | }
84 |
85 | // traverses a node in pos-order and recursively calls itself
86 | func traversePos(data []int, node *Node) []int {
87 | if node.left != nil {
88 | data = traversePos(data, node.left)
89 | }
90 | if node.right != nil {
91 | data = traversePos(data, node.right)
92 | }
93 | count := node.freq
94 | for count != 0 {
95 | data = append(data, node.value)
96 | count--
97 | }
98 | return data
99 | }
100 |
--------------------------------------------------------------------------------
/trees/bst_using_arr/bst_using_arr.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Node is a node of bst
6 | type Node struct {
7 | value int
8 | freq int
9 | height int
10 | }
11 |
12 | // Insert inserts a node in a bst
13 | func Insert(value, index int) {
14 | newNode := &Node{value: value, freq: 1}
15 | if index >= size {
16 | fmt.Println("\n-- Not enough space in array. --")
17 | return
18 | }
19 | if bst[index] == nil {
20 | bst[index] = newNode
21 | } else if bst[index].value == value {
22 | bst[index].freq++
23 | } else {
24 | if value < bst[index].value {
25 | Insert(value, (index*2)+1)
26 | } else {
27 | Insert(value, (index*2)+2)
28 | }
29 | }
30 | }
31 |
32 | // Find finds a key and prints its information
33 | func Find(key int) {
34 | i := 0
35 | for {
36 | if bst[i] != nil {
37 | if bst[i].value == key {
38 | index := i
39 | var sibling *Node
40 | if i%2 == 0 {
41 | i = (i / 2) - 1
42 | sibling = bst[(i*2)+1]
43 | } else {
44 | i /= 2
45 | sibling = bst[(i*2)+2]
46 | }
47 | fmt.Println("\n-- Key found. --")
48 | fmt.Println("Key info is: ", bst[index])
49 | fmt.Println("Parent is: ", bst[i])
50 | fmt.Println("Sibling is: ", sibling)
51 | fmt.Println("Left Child is: ", bst[(index*2)+1])
52 | fmt.Println("Right Child is: ", bst[(index*2)+2])
53 | return
54 | } else if bst[i].value < key {
55 | i = (i * 2) + 2
56 | } else if bst[i].value > key {
57 | i = (i * 2) + 1
58 | }
59 | } else {
60 | fmt.Println("\n-- Key NOT found. --")
61 | return
62 | }
63 | }
64 | }
65 |
66 | var bst [100]*Node
67 | var size int
68 |
69 | func init() {
70 | size = 100
71 | }
72 |
73 | func main() {
74 | i := 0
75 | for i == 0 {
76 | fmt.Println("\n1. INSERT")
77 | fmt.Println("2. DISPLAY using BFS")
78 | fmt.Println("3. DISPLAY using DFS Pre-order")
79 | fmt.Println("4. DISPLAY using DFS In-order")
80 | fmt.Println("5. DISPLAY using DFS Post-order")
81 | fmt.Println("6. FIND")
82 | fmt.Println("7. EXIT")
83 |
84 | var choice int
85 | fmt.Print("Enter your choice: ")
86 | fmt.Scanf("%d\n", &choice)
87 |
88 | switch choice {
89 | case 1:
90 | insNode()
91 | case 2:
92 | fmt.Println("\n", BFS())
93 | case 3:
94 | fmt.Println("\n", DFS("pre"))
95 | case 4:
96 | fmt.Println("\n", DFS("in"))
97 | case 5:
98 | fmt.Println("\n", DFS("pos"))
99 | case 6:
100 | findNode()
101 | case 7:
102 | i = 1
103 | default:
104 | fmt.Println("Command not recognized.")
105 | }
106 | }
107 | }
108 |
109 | func insNode() {
110 | var element int
111 | fmt.Print("Enter the node value that you want to insert: ")
112 | fmt.Scanf("%d\n", &element)
113 | Insert(element, 0)
114 | }
115 |
116 | func findNode() {
117 | var element int
118 | fmt.Print("Enter the value of the key: ")
119 | fmt.Scanf("%d\n", &element)
120 | Find(element)
121 | }
122 |
--------------------------------------------------------------------------------
/trees/bst_using_arr/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // BFS is a bfs traversal technique
4 | func BFS() []int {
5 | var data []int
6 | for i := range bst {
7 | if bst[i] != nil {
8 | count := bst[i].freq
9 | for count != 0 {
10 | data = append(data, bst[i].value)
11 | count--
12 | }
13 | }
14 | }
15 | return data
16 | }
17 |
18 | // DFS is a dfs traversal technique
19 | func DFS(traversalType string) []int {
20 | var data []int
21 | if traversalType == "pre" {
22 | data = traversePre(data, 0)
23 | } else if traversalType == "in" {
24 | data = traverseIn(data, 0)
25 | } else if traversalType == "pos" {
26 | data = traversePos(data, 0)
27 | }
28 | return data
29 | }
30 |
31 | // traverses a tree in pre-order and recursively calls itself
32 | func traversePre(data []int, index int) []int {
33 | if bst[index] != nil {
34 | count := bst[index].freq
35 | for count != 0 {
36 | data = append(data, bst[index].value)
37 | count--
38 | }
39 | data = traversePre(data, (index*2)+1)
40 | data = traversePre(data, (index*2)+2)
41 | }
42 | return data
43 | }
44 |
45 | // traverses a tree in in-order and recursively calls itself
46 | func traverseIn(data []int, index int) []int {
47 | if bst[index] != nil {
48 | data = traverseIn(data, (index*2)+1)
49 | count := bst[index].freq
50 | for count != 0 {
51 | data = append(data, bst[index].value)
52 | count--
53 | }
54 | data = traverseIn(data, (index*2)+2)
55 | }
56 | return data
57 | }
58 |
59 | // traverses a tree in post-order and recursively calls itself
60 | func traversePos(data []int, index int) []int {
61 | if bst[index] != nil {
62 | data = traversePos(data, (index*2)+1)
63 | data = traversePos(data, (index*2)+2)
64 | count := bst[index].freq
65 | for count != 0 {
66 | data = append(data, bst[index].value)
67 | count--
68 | }
69 | }
70 | return data
71 | }
72 |
--------------------------------------------------------------------------------
/trees/bst_using_ll/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // BFS prints the tree using bfs traversal
6 | func (bst *BinarySearchTree) BFS() []int {
7 | if bst.root == nil {
8 | fmt.Print("\n-- Tree is empty. --")
9 | return nil
10 | }
11 | var queue []*Node
12 | var data []int
13 | node := bst.root
14 | queue = append(queue, node)
15 |
16 | for len(queue) != 0 {
17 | node = queue[0]
18 | queue = queue[1:]
19 | count := node.freq
20 | for count != 0 {
21 | data = append(data, node.value)
22 | count--
23 | }
24 | if node.left != nil {
25 | queue = append(queue, node.left)
26 | }
27 | if node.right != nil {
28 | queue = append(queue, node.right)
29 | }
30 | }
31 | return data
32 | }
33 |
34 | // DFS prints the tree using dfs traversal
35 | func (bst *BinarySearchTree) DFS(traverseType string) []int {
36 | if bst.root == nil {
37 | fmt.Println("\n-- Tree is empty. --")
38 | return nil
39 | }
40 |
41 | var data []int
42 | current := bst.root
43 | if traverseType == "pre" {
44 | data = traversePre(data, current)
45 | } else if traverseType == "in" {
46 | data = traverseIn(data, current)
47 | } else if traverseType == "pos" {
48 | data = traversePos(data, current)
49 | }
50 | return data
51 | }
52 |
53 | func traversePre(data []int, node *Node) []int {
54 | count := node.freq
55 | for count != 0 {
56 | data = append(data, node.value)
57 | count--
58 | }
59 | if node.left != nil {
60 | data = traversePre(data, node.left)
61 | }
62 | if node.right != nil {
63 | data = traversePre(data, node.right)
64 | }
65 | return data
66 | }
67 |
68 | func traverseIn(data []int, node *Node) []int {
69 | if node.left != nil {
70 | data = traverseIn(data, node.left)
71 | }
72 | count := node.freq
73 | for count != 0 {
74 | data = append(data, node.value)
75 | count--
76 | }
77 | if node.right != nil {
78 | data = traverseIn(data, node.right)
79 | }
80 | return data
81 | }
82 |
83 | func traversePos(data []int, node *Node) []int {
84 | if node.left != nil {
85 | data = traversePos(data, node.left)
86 | }
87 | if node.right != nil {
88 | data = traversePos(data, node.right)
89 | }
90 | count := node.freq
91 | for count != 0 {
92 | data = append(data, node.value)
93 | count--
94 | }
95 | return data
96 | }
97 |
--------------------------------------------------------------------------------
/trees/simple_bt_using_arr/simple_bt_using_arr.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // Node is a node of bt
6 | type Node struct {
7 | value int
8 | height int
9 | }
10 |
11 | // Insert inserts a node in a bt
12 | func Insert(value, index int) {
13 | flag := 0
14 | newNode := &Node{value: value}
15 | for i := range bt {
16 | if bt[i] == nil {
17 | bt[i] = newNode
18 | flag = 1
19 | return
20 | }
21 | if i == 99 && flag == 0 {
22 | fmt.Println("\n-- Not enough space in array. --")
23 | return
24 | }
25 | }
26 | }
27 |
28 | // Find finds a key and prints its information
29 | func Find(key int) {
30 | for i := range bt {
31 | if bt[i] == nil {
32 | fmt.Println("\n-- Key NOT found. --")
33 | return
34 | } else if bt[(i*2)+1] != nil && bt[(i*2)+1].value == key {
35 | index := (i * 2) + 1
36 | fmt.Println("\n-- Key found. --")
37 | fmt.Println("Key info is:", bt[index])
38 | fmt.Println("Parent is:", bt[i])
39 | fmt.Println("Sibling is:", bt[(i*2)+2])
40 | fmt.Println("Left Child is:", bt[(index*2)+1])
41 | fmt.Println("Right Child is:", bt[(index*2)+2])
42 | return
43 | } else if bt[(i*2)+2] != nil && bt[(i*2)+2].value == key {
44 | index := (i * 2) + 2
45 | fmt.Println("\n-- Key found. --")
46 | fmt.Println("Key info is:", bt[index])
47 | fmt.Println("Parent is:", bt[i])
48 | fmt.Println("Sibling is:", bt[(i*2)+1])
49 | fmt.Println("Left Child is:", bt[(index*2)+1])
50 | fmt.Println("Right Child is:", bt[(index*2)+2])
51 | return
52 | }
53 | }
54 | }
55 |
56 | var bt [100]*Node
57 | var size int
58 |
59 | func init() {
60 | size = 100
61 | }
62 |
63 | func main() {
64 | i := 0
65 | for i == 0 {
66 | fmt.Println("\n1. INSERT")
67 | fmt.Println("2. DISPLAY using BFS")
68 | fmt.Println("3. DISPLAY using DFS Pre-order")
69 | fmt.Println("4. DISPLAY using DFS In-order")
70 | fmt.Println("5. DISPLAY using DFS Post-order")
71 | fmt.Println("6. FIND")
72 | fmt.Println("7. EXIT")
73 |
74 | var choice int
75 | fmt.Print("Enter your choice: ")
76 | fmt.Scanf("%d\n", &choice)
77 |
78 | switch choice {
79 | case 1:
80 | insNode()
81 | case 2:
82 | fmt.Println("\n", BFS())
83 | case 3:
84 | fmt.Println("\n", DFS("pre"))
85 | case 4:
86 | fmt.Println("\n", DFS("in"))
87 | case 5:
88 | fmt.Println("\n", DFS("pos"))
89 | case 6:
90 | findNode()
91 | case 7:
92 | i = 1
93 | default:
94 | fmt.Println("Command not recognized.")
95 | }
96 | }
97 | }
98 |
99 | func insNode() {
100 | var element int
101 | fmt.Print("Enter the node value that you want to insert: ")
102 | fmt.Scanf("%d\n", &element)
103 | Insert(element, 0)
104 | }
105 |
106 | func findNode() {
107 | var element int
108 | fmt.Print("Enter the value of the key: ")
109 | fmt.Scanf("%d\n", &element)
110 | Find(element)
111 | }
112 |
--------------------------------------------------------------------------------
/trees/simple_bt_using_arr/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // BFS is a bfs traversal technique
4 | func BFS() []int {
5 | var data []int
6 | for i := range bt {
7 | if bt[i] != nil {
8 |
9 | data = append(data, bt[i].value)
10 | }
11 | }
12 | return data
13 | }
14 |
15 | // DFS is a dfs traversal technique
16 | func DFS(traversalType string) []int {
17 | var data []int
18 | if traversalType == "pre" {
19 | data = traversePre(data, 0)
20 | } else if traversalType == "in" {
21 | data = traverseIn(data, 0)
22 | } else if traversalType == "pos" {
23 | data = traversePos(data, 0)
24 | }
25 | return data
26 | }
27 |
28 | // traverses a tree in pre-order and recursively calls itself
29 | func traversePre(data []int, index int) []int {
30 | if bt[index] != nil {
31 | data = append(data, bt[index].value)
32 | data = traversePre(data, (index*2)+1)
33 | data = traversePre(data, (index*2)+2)
34 | }
35 | return data
36 | }
37 |
38 | // traverses a tree in in-order and recursively calls itself
39 | func traverseIn(data []int, index int) []int {
40 | if bt[index] != nil {
41 | data = traverseIn(data, (index*2)+1)
42 | data = append(data, bt[index].value)
43 | data = traverseIn(data, (index*2)+2)
44 | }
45 | return data
46 | }
47 |
48 | // traverses a tree in post-order and recursively calls itself
49 | func traversePos(data []int, index int) []int {
50 | if bt[index] != nil {
51 | data = traversePos(data, (index*2)+1)
52 | data = traversePos(data, (index*2)+2)
53 | data = append(data, bt[index].value)
54 | }
55 | return data
56 | }
57 |
--------------------------------------------------------------------------------
/trees/simple_bt_using_ll/traversal.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // BFS prints the tree using bfs traversal
6 | func (bt *BinaryTree) BFS() []int {
7 | if bt.root == nil {
8 | fmt.Print("\n-- Tree is empty. --")
9 | return nil
10 | }
11 | var queue []*Node
12 | var data []int
13 | node := bt.root
14 | queue = append(queue, node)
15 |
16 | for len(queue) != 0 {
17 | node = queue[0]
18 | queue = queue[1:]
19 | data = append(data, node.value)
20 | if node.left != nil {
21 | queue = append(queue, node.left)
22 | }
23 | if node.right != nil {
24 | queue = append(queue, node.right)
25 | }
26 | }
27 | return data
28 | }
29 |
30 | // DFS prints the tree using dfs traversal
31 | func (bt *BinaryTree) DFS(traverseType string) []int {
32 | if bt.root == nil {
33 | fmt.Println("\n-- Tree is empty. --")
34 | return nil
35 | }
36 |
37 | var data []int
38 | current := bt.root
39 | if traverseType == "pre" {
40 | data = traversePre(data, current)
41 | } else if traverseType == "in" {
42 | data = traverseIn(data, current)
43 | } else if traverseType == "pos" {
44 | data = traversePos(data, current)
45 | }
46 | return data
47 | }
48 |
49 | func traversePre(data []int, node *Node) []int {
50 | data = append(data, node.value)
51 | if node.left != nil {
52 | data = traversePre(data, node.left)
53 | }
54 | if node.right != nil {
55 | data = traversePre(data, node.right)
56 | }
57 | return data
58 | }
59 |
60 | func traverseIn(data []int, node *Node) []int {
61 | if node.left != nil {
62 | data = traverseIn(data, node.left)
63 | }
64 | data = append(data, node.value)
65 | if node.right != nil {
66 | data = traverseIn(data, node.right)
67 | }
68 | return data
69 | }
70 |
71 | func traversePos(data []int, node *Node) []int {
72 | if node.left != nil {
73 | data = traversePos(data, node.left)
74 | }
75 | if node.right != nil {
76 | data = traversePos(data, node.right)
77 | }
78 | data = append(data, node.value)
79 | return data
80 | }
81 |
--------------------------------------------------------------------------------