From 06a2cc352e683ebbee9cc9073418fee355deaf00 Mon Sep 17 00:00:00 2001 From: bakurits Date: Tue, 1 Oct 2019 16:10:41 +0400 Subject: [PATCH 1/6] finding prime numbers from 1 to n using eratosthenes sieve --- numerical/prime_finder.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 numerical/prime_finder.go diff --git a/numerical/prime_finder.go b/numerical/prime_finder.go new file mode 100644 index 0000000..013f060 --- /dev/null +++ b/numerical/prime_finder.go @@ -0,0 +1,25 @@ +package main + +// PrimesUpTo finds all prime numbers from 1 to upperBound +// It's implemented using eratosthenes sieve +// Works in O(upperBound) time and space +func PrimesUpTo(upperBound int) []int { + // lp array stores minimal prime divisor for every number from 2 to upperBound + var lp []int + lp = make([]int, upperBound+1) + + // primes array stores primes + var primes []int + + for i := 2; i <= upperBound; i++ { + if lp[i] == 0 { + lp[i] = i + primes = append(primes, i) + } + for j := 0; j < len(primes) && primes[j] <= lp[i] && i*primes[j] <= upperBound; j++ { + lp[i*primes[j]] = primes[j] + } + } + + return primes +} From d95522c19aea5deb48fe370f70d3341cdf6aca18 Mon Sep 17 00:00:00 2001 From: bakurits Date: Tue, 1 Oct 2019 16:51:21 +0400 Subject: [PATCH 2/6] implemented binpow and prime finding --- numerical/bin_pow.go | 14 +++++++ numerical/bin_pow_test.go | 19 ++++++++++ numerical/factorial.go | 17 +++------ numerical/fibonacci.go | 17 +++------ numerical/gcd.go | 69 +++++++++++++++++----------------- numerical/gcd_test.go | 17 +++++---- numerical/prime_finder.go | 2 +- numerical/prime_finder_test.go | 26 +++++++++++++ 8 files changed, 114 insertions(+), 67 deletions(-) create mode 100644 numerical/bin_pow.go create mode 100644 numerical/bin_pow_test.go create mode 100644 numerical/prime_finder_test.go diff --git a/numerical/bin_pow.go b/numerical/bin_pow.go new file mode 100644 index 0000000..e0fd05d --- /dev/null +++ b/numerical/bin_pow.go @@ -0,0 +1,14 @@ +package numerical + +// BinPow evaluates (base ^ deg) % rem +func BinPow(base int, deg int, rem int) int { + var res = 1 + for deg > 0 { + if (deg & 1) > 0 { + res = int(int64(res) * int64(base) % int64(rem)) + } + base = int((int64(base) * int64(base)) % int64(rem)) + deg >>= 1 + } + return res +} diff --git a/numerical/bin_pow_test.go b/numerical/bin_pow_test.go new file mode 100644 index 0000000..27fc934 --- /dev/null +++ b/numerical/bin_pow_test.go @@ -0,0 +1,19 @@ +package numerical + +import "testing" + +// TestBinPow tests binpow function +func TestBinPow(t *testing.T) { + + if BinPow(2, 10, 121323) != 1024 { + t.Error("[Error] BinPow(2, 10) is wrong") + } + + if BinPow(1, 10, 121323) != 1 { + t.Error("[Error] BinPow(1, 10) is wrong") + } + + if BinPow(0, 123123, 2) != 0 { + t.Error("[Error] BinPow(0, 123123) is wrong") + } +} diff --git a/numerical/factorial.go b/numerical/factorial.go index 6536860..51cb6a7 100644 --- a/numerical/factorial.go +++ b/numerical/factorial.go @@ -1,15 +1,8 @@ -package main -import "fmt" +package numerical func factorial(num int) int { - if num == 0 { - return 1 - } - return num * factorial(num - 1) -} - -func main() { - num := 10 - result := factorial(num) - fmt.Println(result) + if num == 0 { + return 1 + } + return num * factorial(num-1) } diff --git a/numerical/fibonacci.go b/numerical/fibonacci.go index 047dc1a..3b61b76 100644 --- a/numerical/fibonacci.go +++ b/numerical/fibonacci.go @@ -1,16 +1,9 @@ -package main -import "fmt" +package numerical //using recursion func fibo(num int) int { - if num <= 1 { - return num - } - return fibo(num -1) + fibo(num - 2) -} - -func main(){ - num := 10 - result := fibo(num) - fmt.Println(result) + if num <= 1 { + return num + } + return fibo(num-1) + fibo(num-2) } diff --git a/numerical/gcd.go b/numerical/gcd.go index ef69478..72af038 100644 --- a/numerical/gcd.go +++ b/numerical/gcd.go @@ -1,47 +1,48 @@ -package gcd +package numerical -func gcd(x uint, y uint) uint { - - var shift uint = 0 +// GCD returns gcd of x and y +func GCD(x uint, y uint) uint { - if x == y { - return x - } + var shift uint = 0 - if x == 0 { - return y - } + if x == y { + return x + } - if y == 0 { - return x - } + if x == 0 { + return y + } - for shift := 0; (x | y) & 1 == 0; shift++ { - x = x >> 1 - y = y >> 1 - } + if y == 0 { + return x + } - for ; (x & 1) == 0 ; { - x = x >> 1 - } + for shift := 0; (x|y)&1 == 0; shift++ { + x = x >> 1 + y = y >> 1 + } - for ; y == 0 ; { - - for ; (y & 1) == 0 ; { - y = y >> 1 - } + for (x & 1) == 0 { + x = x >> 1 + } - if x > y { - t := x - x = y - y = t - } + for y == 0 { - y = y - x + for (y & 1) == 0 { + y = y >> 1 + } - } + if x > y { + t := x + x = y + y = t + } - y = y << shift + y = y - x - return y + } + + y = y << shift + + return y } diff --git a/numerical/gcd_test.go b/numerical/gcd_test.go index 4cc4b59..b7883ee 100644 --- a/numerical/gcd_test.go +++ b/numerical/gcd_test.go @@ -1,18 +1,19 @@ -package gcd +package numerical import "testing" -func Test_gcd(t *testing.T) { +// TestGcd tests gcd +func TestGcd(t *testing.T) { - if gcd(100, 200) != 50 { - t.Error("[Error] gcd(100, 200) is wrong") + if GCD(100, 200) != 50 { + t.Error("[Error] GCD(100, 200) is wrong") } - if gcd(4, 2) != 1 { - t.Error("[Error] gcd(4,2) is wrong") + if GCD(4, 2) != 1 { + t.Error("[Error] GCD(4,2) is wrong") } - if gcd(6, 3) != 3 { - t.Error("[Error] gcd(6,3) is wrong") + if GCD(6, 3) != 3 { + t.Error("[Error] GCD(6,3) is wrong") } } diff --git a/numerical/prime_finder.go b/numerical/prime_finder.go index 013f060..7594407 100644 --- a/numerical/prime_finder.go +++ b/numerical/prime_finder.go @@ -1,4 +1,4 @@ -package main +package numerical // PrimesUpTo finds all prime numbers from 1 to upperBound // It's implemented using eratosthenes sieve diff --git a/numerical/prime_finder_test.go b/numerical/prime_finder_test.go new file mode 100644 index 0000000..b7770bf --- /dev/null +++ b/numerical/prime_finder_test.go @@ -0,0 +1,26 @@ +package numerical + +import "testing" + +func arrayEquals(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} + +// TestPrimeFinder tests prime finding +func TestPrimeFinder(t *testing.T) { + + if !arrayEquals(PrimesUpTo(10), []int{2, 3, 5, 7}) { + t.Error("[Error] PrimesUpTo(10) is wrong") + } + if len(PrimesUpTo(100)) != 25 { + t.Error("[Error] PrimesUpTo(100) is wrong") + } +} From ba2e1413a2eed92e4976e054df92afb356b38f50 Mon Sep 17 00:00:00 2001 From: Ata Atasoy <40474912+AtaAtasoy@users.noreply.github.com> Date: Sat, 23 Nov 2019 16:04:40 +0300 Subject: [PATCH 3/6] add treesort --- sorting/treesort.go | 63 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 sorting/treesort.go diff --git a/sorting/treesort.go b/sorting/treesort.go new file mode 100644 index 0000000..0da703c --- /dev/null +++ b/sorting/treesort.go @@ -0,0 +1,63 @@ +package main + +import "fmt" + +// definition of a bst node +type node struct { + val int + left *node + right *node +} + +// definition of a node +type btree struct { + root *node +} + +// allocating a new node +func newNode(val int) *node { + return &node{val, nil, nil} +} + +// insert nodes into a binary search tree +func insert(root *node, val int) *node { + if root == nil { + return newNode(val) + } + if val < root.val { + root.left = insert(root.left, val) + } else { + root.right = insert(root.right, val) + } + return root +} + +// inorder traversal algorithm +// Copies the elements of the bst to the array in sorted order +func inorderCopy(n *node, array []int, index *int) { + if n != nil { + inorderCopy(n.left, array, index) + array[*index] = n.val + *index++ + inorderCopy(n.right, array, index) + } +} + +func treesort(array []int, tree *btree) { + // build the binary search tree + for _, element := range array { + tree.root = insert(tree.root, element) + } + index := 0 + // perform inorder traversal to get the elements in sorted order + inorderCopy(tree.root, array, &index) +} + +// tester +func main() { + tree := &btree{nil} + numbers := []int{5, 4, 3, 2, 1, -1, 0} + fmt.Println("numbers : ", numbers) + treesort(numbers, tree) + fmt.Println("numbers : ", numbers) +} From b17b4cbb39019ec783981e95e4720cf4ae8e0c98 Mon Sep 17 00:00:00 2001 From: dwij2812 Date: Fri, 25 Sep 2020 16:06:32 +0530 Subject: [PATCH 4/6] Added Interpolation Search --- README.md | 1 + searching/interpolationSearch.go | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 searching/interpolationSearch.go diff --git a/README.md b/README.md index a261c2d..a2cd36b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Algorithms * [binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) * [linear search](https://en.wikipedia.org/wiki/Linear_search) * [jump search](https://en.wikipedia.org/wiki/Jump_search) + * [interpolation search](https://en.wikipedia.org/wiki/Interpolation_search) #### Collections diff --git a/searching/interpolationSearch.go b/searching/interpolationSearch.go new file mode 100644 index 0000000..9ff4ed9 --- /dev/null +++ b/searching/interpolationSearch.go @@ -0,0 +1,65 @@ +package main + +import "fmt" + +func InterpolationSearch(array []int, key int) int { + + min, max := array[0], array[len(array)-1] + + low, high := 0, len(array)-1 + + for { + if key < min { + return low + } + + if key > max { + return high + 1 + } + + // make a guess of the location + var guess int + if high == low { + guess = high + } else { + size := high - low + offset := int(float64(size-1) * (float64(key-min) / float64(max-min))) + guess = low + offset + } + + // maybe we found it? + if array[guess] == key { + // scan backwards for start of value range + for guess > 0 && array[guess-1] == key { + guess-- + } + return guess + } + + // if we guessed to high, guess lower or vice versa + if array[guess] > key { + high = guess - 1 + max = array[high] + } else { + low = guess + 1 + min = array[low] + } + } +} + +func main() { + searchValue := 0 + + arr := []int{1, 5, 100, 0, -100, 15, 4, 102, 30, 1000} + fmt.Println(arr) + + var index = InterpolationSearch(arr, searchValue) + + if index < 0 { + fmt.Println("Not found") + return + } else { + fmt.Println("Found at position: ", index) + return + } +} From d7efb7b1e36cfe94318c99f494f4e61b07767689 Mon Sep 17 00:00:00 2001 From: dwij2812 Date: Fri, 25 Sep 2020 21:56:00 +0530 Subject: [PATCH 5/6] Added Breadth First Search --- README.md | 2 +- searching/breadthFirstSearch.go | 72 ++++++++++++++++++++++++++++++++ searching/interpolationSearch.go | 65 ---------------------------- 3 files changed, 73 insertions(+), 66 deletions(-) create mode 100644 searching/breadthFirstSearch.go delete mode 100644 searching/interpolationSearch.go diff --git a/README.md b/README.md index a2cd36b..f056ffb 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Algorithms * [binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) * [linear search](https://en.wikipedia.org/wiki/Linear_search) * [jump search](https://en.wikipedia.org/wiki/Jump_search) - * [interpolation search](https://en.wikipedia.org/wiki/Interpolation_search) + * [breadth-first search](https://en.wikipedia.org/wiki/Breadth-first_search) #### Collections diff --git a/searching/breadthFirstSearch.go b/searching/breadthFirstSearch.go new file mode 100644 index 0000000..7719d3f --- /dev/null +++ b/searching/breadthFirstSearch.go @@ -0,0 +1,72 @@ +package main + +import "fmt" + +func getIdx(target int, nodes []int) int { + for i := 0; i < len(nodes); i++ { + if nodes[i] == target { + return i + } + } + return -1 +} + +func notExist(target int, slice []int) bool { + for i := 0; i < len(slice); i++ { + if slice[i] == target { + return false + } + } + return true +} + +func breadthFirstSearch(start, end int, nodes []int, edges [][]bool) bool { + var route []int + var queue []int + startIdx := getIdx(start, nodes) + queue = append(queue, startIdx) + for len(queue) > 0 { + now := queue[0] + route = append(route, nodes[now]) + if len(queue) > 1 { + queue = queue[1:] + } else { + queue = queue[0:] + } + for i := 0; i < len(edges[now]); i++ { + if edges[now][i] && notExist(i, queue) { + queue = append(queue, i) + } + edges[now][i] = false + edges[i][now] = false + } + if route[len(route)-1] == end { + return true + } + } + return false +} + +func main() { + nodes := []int{ + 1, 2, 3, 4, 5, 6, + } + /* + sample graph + ①-② + | | + ③-④-⑤-⑥ + */ + edges := [][]bool{ + {false, true, true, false, false, false}, + {true, false, false, true, false, false}, + {true, false, false, true, false, false}, + {false, true, true, false, true, false}, + {false, false, false, true, false, true}, + {false, false, false, false, true, false}, + } + start := 1 + end := 6 + result := breadthFirstSearch(start, end, nodes, edges) + fmt.Println(result) +} diff --git a/searching/interpolationSearch.go b/searching/interpolationSearch.go deleted file mode 100644 index 9ff4ed9..0000000 --- a/searching/interpolationSearch.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import "fmt" - -func InterpolationSearch(array []int, key int) int { - - min, max := array[0], array[len(array)-1] - - low, high := 0, len(array)-1 - - for { - if key < min { - return low - } - - if key > max { - return high + 1 - } - - // make a guess of the location - var guess int - if high == low { - guess = high - } else { - size := high - low - offset := int(float64(size-1) * (float64(key-min) / float64(max-min))) - guess = low + offset - } - - // maybe we found it? - if array[guess] == key { - // scan backwards for start of value range - for guess > 0 && array[guess-1] == key { - guess-- - } - return guess - } - - // if we guessed to high, guess lower or vice versa - if array[guess] > key { - high = guess - 1 - max = array[high] - } else { - low = guess + 1 - min = array[low] - } - } -} - -func main() { - searchValue := 0 - - arr := []int{1, 5, 100, 0, -100, 15, 4, 102, 30, 1000} - fmt.Println(arr) - - var index = InterpolationSearch(arr, searchValue) - - if index < 0 { - fmt.Println("Not found") - return - } else { - fmt.Println("Found at position: ", index) - return - } -} From bc5946ee84a8ab336a56343679f4764dac53684d Mon Sep 17 00:00:00 2001 From: dwij2812 Date: Wed, 30 Sep 2020 22:07:11 +0530 Subject: [PATCH 6/6] Added Radix Sort --- README.md | 1 + sorting/radix_sort.go | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 sorting/radix_sort.go diff --git a/README.md b/README.md index a261c2d..74185d0 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Algorithms * [heap sort](https://en.wikipedia.org/wiki/Heapsort) * [Shell sort](https://en.wikipedia.org/wiki/Shellsort) * [counting sort](https://en.wikipedia.org/wiki/Counting_sort) + * [radix sort](https://en.wikipedia.org/wiki/Radix_sort) #### Searching diff --git a/sorting/radix_sort.go b/sorting/radix_sort.go new file mode 100644 index 0000000..5ec5432 --- /dev/null +++ b/sorting/radix_sort.go @@ -0,0 +1,47 @@ +package main + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +const digit = 4 +const maxbit = -1 << 31 + +func main() { + + var data = []int32{421, 15, -175, 90, -2, 214, -52, -166} + fmt.Println("\n--- Unsorted --- \n\n", data) + radixsort(data) + fmt.Println("\n--- Sorted ---\n\n", data, "\n") +} + +func radixsort(data []int32) { + buf := bytes.NewBuffer(nil) + ds := make([][]byte, len(data)) + for i, e := range data { + binary.Write(buf, binary.LittleEndian, e^maxbit) + b := make([]byte, digit) + buf.Read(b) + ds[i] = b + } + countingSort := make([][][]byte, 256) + for i := 0; i < digit; i++ { + for _, b := range ds { + countingSort[b[i]] = append(countingSort[b[i]], b) + } + j := 0 + for k, bs := range countingSort { + copy(ds[j:], bs) + j += len(bs) + countingSort[k] = bs[:0] + } + } + var w int32 + for i, b := range ds { + buf.Write(b) + binary.Read(buf, binary.LittleEndian, &w) + data[i] = w ^ maxbit + } +}