From 759ae35e7cfed585009fe7b468c97f719118d34e Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Tue, 15 Dec 2020 23:27:02 +0530 Subject: [PATCH 1/7] Add files via upload --- binary-tree/binarysearchtree.go | 126 ++++++++++++++++++++++++++++++++ binary-tree/binarytree.go | 110 ++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 binary-tree/binarysearchtree.go create mode 100644 binary-tree/binarytree.go diff --git a/binary-tree/binarysearchtree.go b/binary-tree/binarysearchtree.go new file mode 100644 index 0000000..48e38f5 --- /dev/null +++ b/binary-tree/binarysearchtree.go @@ -0,0 +1,126 @@ +// Binary search tree + + +package binarySearchTree + +// package main + +import "fmt" + +type node struct { + val int + left *node + right *node +} + +type btree struct { + root *node +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func newNode(val int) *node { + return &node{val, nil, nil} +} + +func inorder(n *node) { + if n != nil { + inorder(n.left) + fmt.Print(n.val, " ") + inorder(n.right) + } +} + +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 +} + +func inorderSuccessor(root *node) *node { + cur := root + for cur.left != nil { + cur = cur.left + } + return cur +} + +func bst_delete(root *node, val int) *node { + if root == nil { + return nil + } + if val < root.val { + root.left = bst_delete(root.left, val) + } else if val > root.val { + root.right = bst_delete(root.right, val) + } else { + // this is the node to delete + // node with one child + if root.left == nil { + return root.right + } else if root.right == nil { + return root.left + } else { + n := root.right + d := inorderSuccessor(n) + d.left = root.left + return root.right + } + } + return root +} + +// helper function for t.depth +func _calculate_depth(n *node, depth int) int { + if n == nil { + return depth + } + return max(_calculate_depth(n.left, depth+1), _calculate_depth(n.right, depth+1)) +} + +func (t *btree) depth() int { + return _calculate_depth(t.root, 0) +} + + +func main() { + t := &btree{nil} + inorder(t.root) + t.root = insert(t.root, 30) + + t.root = insert(t.root, 20) + t.root = insert(t.root, 15) + t.root = insert(t.root, 10) + t.root = insert(t.root, 12) + t.root = insert(t.root, 9) + t.root = insert(t.root, 11) + t.root = insert(t.root, 17) + fmt.Print(t.depth(), "\n") + inorder(t.root) + fmt.Print("\n") + t.root = bst_delete(t.root, 10) + inorder(t.root) + fmt.Print("\n") + t.root = bst_delete(t.root, 30) + inorder(t.root) + fmt.Print("\n") + t.root = bst_delete(t.root, 15) + inorder(t.root) + fmt.Print("\n") + t.root = bst_delete(t.root, 20) + inorder(t.root) + fmt.Print("\n") + fmt.Print(t.depth(), "\n") +} + diff --git a/binary-tree/binarytree.go b/binary-tree/binarytree.go new file mode 100644 index 0000000..f85563c --- /dev/null +++ b/binary-tree/binarytree.go @@ -0,0 +1,110 @@ +// basic binary tree and related operations + +package binarytree + +// package main + +import "fmt" + +type node struct { + val int + left *node + right *node +} + +type btree struct { + root *node +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func newNode(val int) *node { + n := &node{val, nil, nil} + return n +} + +func inorder(n *node) { + if n == nil { + return + } + inorder(n.left) + fmt.Print(n.val, " ") + inorder(n.right) +} + +func preorder(n *node) { + if n == nil { + return + } + fmt.Print(n.val, " ") + preorder(n.left) + preorder(n.right) +} + +func postorder(n *node) { + if n == nil { + return + } + postorder(n.left) + postorder(n.right) + fmt.Print(n.val, " ") +} + +func levelorder(root *node) { + var q []*node // queue + var n *node // temporary node + + q = append(q, root) + + for len(q) != 0 { + n, q = q[0], q[1:] + fmt.Print(n.val, " ") + if n.left != nil { + q = append(q, n.left) + } + if n.right != nil { + q = append(q, n.right) + } + } +} + +// helper function for t.depth +func _calculate_depth(n *node, depth int) int { + if n == nil { + return depth + } + return max(_calculate_depth(n.left, depth+1), _calculate_depth(n.right, depth+1)) +} + +func (t *btree) depth() int { + return _calculate_depth(t.root, 0) +} + +/* +func main() { + t := btree{nil} + t.root = newNode(0) + t.root.left = newNode(1) + t.root.right = newNode(2) + t.root.left.left = newNode(3) + t.root.left.right = newNode(4) + t.root.right.left = newNode(5) + t.root.right.right = newNode(6) + t.root.right.right.right = newNode(10) + + inorder(t.root) + fmt.Print("\n") + preorder(t.root) + fmt.Print("\n") + postorder(t.root) + fmt.Print("\n") + levelorder(t.root) + fmt.Print("\n") + fmt.Print(t.depth(), "\n") +} +*/ From c06f51f8cb3603dc8eca520f84d0817aaa8d026e Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Tue, 22 Dec 2020 11:49:34 +0530 Subject: [PATCH 2/7] Add files via upload --- dynamic-array/dynamicarray.go | 114 ++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 dynamic-array/dynamicarray.go diff --git a/dynamic-array/dynamicarray.go b/dynamic-array/dynamicarray.go new file mode 100644 index 0000000..70b11b3 --- /dev/null +++ b/dynamic-array/dynamicarray.go @@ -0,0 +1,114 @@ +package dynamic-array + +import ( + "errors" +) + +var defaultCapacity = 10 + +type dynamicArray struct { + size int + capacity int + elementData []interface{} +} + +func (da *dynamicArray) put(index int, element interface{}) error { + err := da.checkRangeFromIndex(index) + + if err != nil { + return err + } + + da.elementData[index] = element + + return nil +} + +func (da *dynamicArray) add(element interface{}) { + if da.size == da.capacity { + da.newCapacity() + } + + da.elementData[da.size] = element + da.size++ +} + +func (da *dynamicArray) remove(index int) error { + err := da.checkRangeFromIndex(index) + + if err != nil { + return err + } + + copy(da.elementData[index:], da.elementData[index+1:da.size]) + da.elementData[da.size-1] = nil + + da.size-- + + return nil +} + +func (da *dynamicArray) get(index int) (interface{}, error) { + err := da.checkRangeFromIndex(index) + + if err != nil { + return nil, err + } + + return da.elementData[index], nil +} + +func (da *dynamicArray) isEmpty() bool { + return da.size == 0 +} + +func (da *dynamicArray) getData() []interface{} { + return da.elementData[:da.size] +} + +func (da *dynamicArray) checkRangeFromIndex(index int) error { + if index >= da.size || index < 0 { + return errors.New("index out of range") + } + return nil +} + +func (da *dynamicArray) newCapacity() { + if da.capacity == 0 { + da.capacity = defaultCapacity + } else { + da.capacity = da.capacity << 1 + } + + newDataElement := make([]interface{}, da.capacity) + + copy(newDataElement, da.elementData) + + da.elementData = newDataElement +} + +// func main() { +// numbers := dynamicArray{} +// fmt.Println(numbers.isEmpty()) + +// numbers.add(10) +// numbers.add(20) +// numbers.add(30) +// numbers.add(40) +// numbers.add(50) + +// fmt.Println(numbers.isEmpty()) + +// fmt.Println(numbers.getData()) + +// numbers.remove(1) + +// fmt.Println(numbers.getData()) + +// numberFound, _ := numbers.get(1) +// fmt.Println(numberFound) + +// numbers.put(0, 100) +// fmt.Println(numbers.getData()) +// } + From 7d22985f8ce454c0302ca32ea3961288beb6f2cf Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Wed, 23 Dec 2020 21:21:32 +0530 Subject: [PATCH 3/7] Add files via upload --- hashmap/hashmap.go | 122 ++++++++++++++++++++++++++++++++++++++++ hashmap/hashmap_test.go | 28 +++++++++ 2 files changed, 150 insertions(+) create mode 100644 hashmap/hashmap.go create mode 100644 hashmap/hashmap_test.go diff --git a/hashmap/hashmap.go b/hashmap/hashmap.go new file mode 100644 index 0000000..bd03e64 --- /dev/null +++ b/hashmap/hashmap.go @@ -0,0 +1,122 @@ +package hashmap + +import ( + "fmt" + "hash/fnv" +) + +var defaultCapacity uint64 = 1 << 10 + +type node struct { + key interface{} + value interface{} + next *node +} + +// HashMap is golang implementation of hashmap +type HashMap struct { + capacity uint64 + size uint64 + table []*node +} + +// New return new HashMap instance +func New() *HashMap { + return &HashMap{ + capacity: defaultCapacity, + table: make([]*node, defaultCapacity), + } +} + +// Get returns value associated with given key +func (hm *HashMap) Get(key interface{}) interface{} { + node := hm.getNodeByHash(hm.hash(key)) + + if node != nil { + return node.value + } + + return nil +} + +// Put puts new key value in hashmap +func (hm *HashMap) Put(key interface{}, value interface{}) interface{} { + return hm.putValue(hm.hash(key), key, value) +} + +// Contains checks if given key is stored in hashmap +func (hm *HashMap) Contains(key interface{}) bool { + node := hm.getNodeByHash(hm.hash(key)) + return node != nil +} + +func (hm *HashMap) putValue(hash uint64, key interface{}, value interface{}) interface{} { + if hm.capacity == 0 { + hm.capacity = defaultCapacity + hm.table = make([]*node, defaultCapacity) + } + + node := hm.getNodeByHash(hash) + + if node == nil { + hm.table[hash] = newNode(key, value) + + } else if node.key == key { + hm.table[hash] = newNodeWithNext(key, value, node) + return value + + } else { + hm.resize() + return hm.putValue(hash, key, value) + } + + hm.size++ + + return value + +} + +func (hm *HashMap) getNodeByHash(hash uint64) *node { + return hm.table[hash] +} + +func (hm *HashMap) resize() { + hm.capacity <<= 1 + + tempTable := hm.table + + hm.table = make([]*node, hm.capacity) + + for i := 0; i < len(tempTable); i++ { + node := tempTable[i] + if node == nil { + continue + } + + hm.table[hm.hash(node.key)] = node + } +} + +func newNode(key interface{}, value interface{}) *node { + return &node{ + key: key, + value: value, + } +} + +func newNodeWithNext(key interface{}, value interface{}, next *node) *node { + return &node{ + key: key, + value: value, + next: next, + } +} + +func (hm *HashMap) hash(key interface{}) uint64 { + h := fnv.New64a() + _, _ = h.Write([]byte(fmt.Sprintf("%v", key))) + + hashValue := h.Sum64() + + return (hm.capacity - 1) & (hashValue ^ (hashValue >> 16)) +} diff --git a/hashmap/hashmap_test.go b/hashmap/hashmap_test.go new file mode 100644 index 0000000..8b65fc7 --- /dev/null +++ b/hashmap/hashmap_test.go @@ -0,0 +1,28 @@ +package hashmap_test + +import ( + "TheAlgorithms/Go/datastructures/hashmap" + "fmt" + "testing" +) + +func TestHashMap_Contains(t *testing.T) { + + mp := hashmap.New() + + mp.Put("test-1", 10) + fmt.Println(mp.Get("test-1")) + + mp.Put("test-1", 20) + mp.Put("test-2", 30) + mp.Put(1, 40) + + fmt.Println(mp.Get("test-1")) + fmt.Println(mp.Get("test-2")) + fmt.Println(mp.Get(1)) + + fmt.Println(mp.Contains(2)) + fmt.Println(mp.Contains(1)) + fmt.Println(mp.Contains("test-1")) + +} From b2a69683c98a37cb4dda54cd3f5855bc46794237 Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Thu, 24 Dec 2020 16:35:33 +0530 Subject: [PATCH 4/7] Add files via upload --- linkedlist/doublylinkedlist.go | 156 ++++++++++++++++++ .../singlelinkedlist/single-linkedlist.go | 113 +++++++++++++ .../single-linkedlist_test.go | 67 ++++++++ linkedlist/singlylinkedlist.go | 102 ++++++++++++ 4 files changed, 438 insertions(+) create mode 100644 linkedlist/doublylinkedlist.go create mode 100644 linkedlist/singlelinkedlist/single-linkedlist.go create mode 100644 linkedlist/singlelinkedlist/single-linkedlist_test.go create mode 100644 linkedlist/singlylinkedlist.go diff --git a/linkedlist/doublylinkedlist.go b/linkedlist/doublylinkedlist.go new file mode 100644 index 0000000..9b05130 --- /dev/null +++ b/linkedlist/doublylinkedlist.go @@ -0,0 +1,156 @@ +// demonstration of doubly linked list in golang + +package linkedlist + +// package main + +import "fmt" + +type node struct { + val int + next *node + prev *node +} + +type doublelinkedlist struct { + head *node +} + +// to avoid mistakes when using pointer vs struct for new node creation +func newNode(val int) *node { + n := &node{} + n.val = val + n.next = nil + n.prev = nil + return n +} + +func (ll *doublelinkedlist) addAtBeg(val int) { + n := newNode(val) + n.next = ll.head + ll.head = n +} + +func (ll *doublelinkedlist) addAtEnd(val int) { + n := newNode(val) + + if ll.head == nil { + ll.head = n + return + } + + cur := ll.head + for ; cur.next != nil; cur = cur.next { + } + cur.next = n + n.prev = cur +} + +func (ll *doublelinkedlist) delAtBeg() int { + if ll.head == nil { + return -1 + } + + cur := ll.head + ll.head = cur.next + + if ll.head != nil { + ll.head.prev = nil + } + + return cur.val +} + +func (ll *doublelinkedlist) delAtEnd() int { + // no item + if ll.head == nil { + return -1 + } + + // only one item + if ll.head.next == nil { + return ll.delAtBeg() + } + + // more than one, go to second last + cur := ll.head + for ; cur.next.next != nil; cur = cur.next { + } + + retval := cur.next.val + cur.next = nil + return retval +} + +func (ll *doublelinkedlist) count() int { + var ctr int = 0 + + for cur := ll.head; cur != nil; cur = cur.next { + ctr += 1 + } + + return ctr +} + +func (ll *doublelinkedlist) reverse() { + var prev, next *node + cur := ll.head + + for cur != nil { + next = cur.next + cur.next = prev + cur.prev = next + prev = cur + cur = next + } + + ll.head = prev +} + +func (ll *doublelinkedlist) display() { + for cur := ll.head; cur != nil; cur = cur.next { + fmt.Print(cur.val, " ") + } + + fmt.Print("\n") +} + +func (ll *doublelinkedlist) displayReverse() { + if ll.head == nil { + return + } + var cur *node + for cur = ll.head; cur.next != nil; cur = cur.next { + } + + for ; cur != nil; cur = cur.prev { + fmt.Print(cur.val, " ") + } + + fmt.Print("\n") +} + +/* +func main() { + ll := doublelinkedlist{} + + ll.addAtBeg(10) + ll.addAtEnd(20) + ll.display() + ll.addAtBeg(30) + ll.display() + + ll.reverse() + ll.display() + ll.displayReverse() + + fmt.Print(ll.delAtBeg(), "\n") + fmt.Print(ll.delAtEnd(), "\n") + fmt.Print("Display") + ll.display() + fmt.Print(ll.delAtBeg(), "\n") + ll.display() + fmt.Print(ll.delAtBeg(), "\n") + ll.display() +} +*/ diff --git a/linkedlist/singlelinkedlist/single-linkedlist.go b/linkedlist/singlelinkedlist/single-linkedlist.go new file mode 100644 index 0000000..e280aa7 --- /dev/null +++ b/linkedlist/singlelinkedlist/single-linkedlist.go @@ -0,0 +1,113 @@ +package singlelinkedlist + +// demonstration of singly linked list in golang +import "fmt" + +type node struct { + Val interface{} + Next *node +} + +type singlelinkedlist struct { + length int + Head *node +} + +// CreateList returns a new instance of a linked list +func CreateList() *singlelinkedlist { + return &singlelinkedlist{} +} + +// to avoid mistakes when using pointer vs struct for new node creation +func newNode(val interface{}) *node { + return &node{val, nil} +} + +// AddAtBeg adds a new node with given value at the beginning of the list. +func (ll *singlelinkedlist) AddAtBeg(val interface{}) { + n := newNode(val) + n.Next = ll.Head + ll.Head = n + ll.length++ +} + +// AddAtEnd adds a new node with given value at the end of the list. +func (ll *singlelinkedlist) AddAtEnd(val int) { + n := newNode(val) + + if ll.Head == nil { + ll.Head = n + ll.length++ + return + } + + cur := ll.Head + for ; cur.Next != nil; cur = cur.Next { + } + cur.Next = n + ll.length++ +} + +// DelAtBeg deletes the node at the head(beginning) of the list and returns its value. Returns -1 if the list is empty. +func (ll *singlelinkedlist) DelAtBeg() interface{} { + if ll.Head == nil { + return -1 + } + + cur := ll.Head + ll.Head = cur.Next + ll.length-- + + return cur.Val +} + +// DelAtEnd deletes the node at the tail(end) of the list and returns its value. Returns -1 if the list is empty. +func (ll *singlelinkedlist) DelAtEnd() interface{} { + if ll.Head == nil { + return -1 + } + + if ll.Head.Next == nil { + return ll.DelAtBeg() + } + + cur := ll.Head + + for ; cur.Next.Next != nil; cur = cur.Next { + } + + retval := cur.Next.Val + cur.Next = nil + ll.length-- + return retval + +} + +// Count returns the current size of the list. +func (ll *singlelinkedlist) Count() int { + return ll.length +} + +// Reverse reverses the list. +func (ll *singlelinkedlist) Reverse() { + var prev, Next *node + cur := ll.Head + + for cur != nil { + Next = cur.Next + cur.Next = prev + prev = cur + cur = Next + } + + ll.Head = prev +} + +// Display prints out the elements of the list. +func (ll *singlelinkedlist) Display() { + for cur := ll.Head; cur != nil; cur = cur.Next { + fmt.Print(cur.Val, " ") + } + + fmt.Print("\n") +} diff --git a/linkedlist/singlelinkedlist/single-linkedlist_test.go b/linkedlist/singlelinkedlist/single-linkedlist_test.go new file mode 100644 index 0000000..c9eb951 --- /dev/null +++ b/linkedlist/singlelinkedlist/single-linkedlist_test.go @@ -0,0 +1,67 @@ +package singlelinkedlist + +import ( + "reflect" + "testing" +) + +func TestLinkedList(t *testing.T) { + list := CreateList() + list.AddAtBeg(1) + list.AddAtBeg(2) + list.AddAtBeg(3) + + t.Run("Test AddAtBeg()", func(t *testing.T) { + want := []interface{}{3, 2, 1} + got := []interface{}{} + current := list.Head + got = append(got, current.Val) + for current.Next != nil { + current = current.Next + got = append(got, current.Val) + } + if !reflect.DeepEqual(got, want) { + t.Errorf("got: %v, want: %v", got, want) + } + }) + + list.AddAtEnd(4) + + t.Run("Test AddAtEnd()", func(t *testing.T) { + want := []interface{}{3, 2, 1, 4} + got := []interface{}{} + current := list.Head + got = append(got, current.Val) + for current.Next != nil { + current = current.Next + got = append(got, current.Val) + } + if !reflect.DeepEqual(got, want) { + t.Errorf("got: %v, want: %v", got, want) + } + }) + + t.Run("Test DelAtBeg()", func(t *testing.T) { + want := interface{}(3) + got := list.DelAtBeg() + if got != want { + t.Errorf("got: %v, want: %v", got, want) + } + }) + + t.Run("Test DelAtEnd()", func(t *testing.T) { + want := interface{}(4) + got := list.DelAtEnd() + if got != want { + t.Errorf("got: %v, want: %v", got, want) + } + }) + + t.Run("Test Count()", func(t *testing.T) { + want := 2 + got := list.Count() + if got != want { + t.Errorf("got: %v, want: %v", got, want) + } + }) +} diff --git a/linkedlist/singlylinkedlist.go b/linkedlist/singlylinkedlist.go new file mode 100644 index 0000000..be23eb7 --- /dev/null +++ b/linkedlist/singlylinkedlist.go @@ -0,0 +1,102 @@ +package linkedlist + +import "fmt" + +/* v is the value of node; next is the pointer to next node */ +type node struct { + v int + next *node +} + +/* first node, called head. It points from first node to last node */ +var head *node = nil + +func (l *node) pushFront(val int) *node { + /* if there's no nodes, head points to l (first node) */ + if head == nil { + l.v = val + l.next = nil + head = l + return l + } else { + /* create a new node equals to head */ + nnode := new(node) + nnode = head + /* create a second node with new value and `next -> nnode` + * is this way, nnode2 is before nnode + */ + nnode2 := &node{ + v: val, + next: nnode, + } + /* now head is equals nnode2 */ + head = nnode2 + return head + } +} + +func (l *node) pushBack(val int) *node { + /* if there's no nodes, head points to l (first node) */ + if head == nil { + l.v = val + l.next = nil + head = l + return l + } else { + /* read all list to last node */ + for l.next != nil { + l = l.next + } + /* allocate a new portion of memory */ + l.next = new(node) + l.next.v = val + l.next.next = nil + return l + } +} + +func (l *node) popFront() *node { + if head == nil { + return head + } + /* create a new node equals to first node pointed by head */ + cpnode := new(node) + cpnode = head.next + + /* now head is equals cpnode (second node) */ + head = cpnode + + return head +} + +func (l *node) popBack() *node { + if head == nil { + return head + } + /* create a new node equals to head */ + cpnode := new(node) + cpnode = head + + /* read list to the penultimate node */ + for cpnode.next.next != nil { + cpnode = cpnode.next + } + /* the penultimate node points to null. In this way the last node is deleted */ + cpnode.next = nil + return head +} + +func main() { + lista := new(node) + lista.pushBack(25).pushBack(24).pushBack(32) /* lista: 25 24 32 */ + lista.pushBack(56) /* lista: 25 24 32 56 */ + lista.pushFront(36) /* lista: 36 25 24 32 56 */ + lista.popFront() /* lista: 25 24 32 56 */ + lista.popBack() /* lista: 25 24 32 */ + + /* read the list until head is not nil */ + for head != nil { + fmt.Printf("%d ", head.v) + head = head.next /*head points to next node */ + } +} From 8812eb3acb53d209d677ee5bb9ff1fbe29d6a1b8 Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Fri, 25 Dec 2020 13:22:42 +0530 Subject: [PATCH 5/7] Add files via upload --- trie/trie.go | 46 +++++++++++++++++++++++++++++++ trie/trie_test.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 trie/trie.go create mode 100644 trie/trie_test.go diff --git a/trie/trie.go b/trie/trie.go new file mode 100644 index 0000000..df3c87a --- /dev/null +++ b/trie/trie.go @@ -0,0 +1,46 @@ +// Package trie provides Trie data structures in golang. +// +// Wikipedia: https://en.wikipedia.org/wiki/Trie +package trie + +// Node represents each node in Trie. +type Node struct { + children map[rune]*Node // map children nodes + isLeaf bool // current node value +} + +// NewNode creates a new Trie node with initialized +// children map. +func NewNode() *Node { + n := &Node{} + n.children = make(map[rune]*Node) + n.isLeaf = false + return n +} + +// Insert inserts words at a Trie node. +func (n *Node) Insert(s string) { + curr := n + for _, c := range s { + next, ok := curr.children[c] + if !ok { + next = NewNode() + curr.children[c] = next + } + curr = next + } + curr.isLeaf = true +} + +// Find finds words at a Trie node. +func (n *Node) Find(s string) bool { + curr := n + for _, c := range s { + next, ok := curr.children[c] + if !ok { + return false + } + curr = next + } + return true +} diff --git a/trie/trie_test.go b/trie/trie_test.go new file mode 100644 index 0000000..4c6c949 --- /dev/null +++ b/trie/trie_test.go @@ -0,0 +1,70 @@ +package trie + +import ( + "testing" +) + +func TestTrie(t *testing.T) { + n := NewNode() + + insertWords := [...]string{ + "nikola", + "tesla", + } + checkWords := map[string]bool{ + "thomas": false, + "edison": false, + "nikola": true, + } + + for _, w := range insertWords { + n.insert(w) + t.Logf( + "added \"%s\" to the Trie.", + w, + ) + } + + for k, v := range checkWords { + ok := n.find(k) + if ok != v { + t.Fatalf( + "\"%s\" is supposed to be %sin the Trie.", + k, + map[bool]string{true: "", false: "NOT "}[v], + ) + } + t.Logf( + "\"%s\" is %sin the Trie.", + k, + map[bool]string{true: "", false: "NOT "}[ok], + ) + } +} + +func BenchmarkTrie(b *testing.B) { + for i := 0; i < b.N; i++ { + n := NewNode() + + n.insert("nikola") + n.insert("tesla") + + n.find("thomas") + n.find("edison") + n.find("nikola") + } +} + +func ExampleNode() { + // creates a new node + node := NewNode() + + // adds words + node.insert("nikola") + node.insert("tesla") + + // finds words + node.find("thomas") // false + node.find("edison") // false + node.find("nikola") // true +} From 17572d934d6b118188b0f693dac0a74973efa2db Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Sat, 26 Dec 2020 23:51:15 +0530 Subject: [PATCH 6/7] Add files via upload --- graphs/breathfirstsearch.go | 72 +++++++++++++++++++++++++++++++++++++ graphs/depthfirstsearch.go | 72 +++++++++++++++++++++++++++++++++++++ graphs/floydwarshall.go | 64 +++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 graphs/breathfirstsearch.go create mode 100644 graphs/depthfirstsearch.go create mode 100644 graphs/floydwarshall.go diff --git a/graphs/breathfirstsearch.go b/graphs/breathfirstsearch.go new file mode 100644 index 0000000..66e8c7e --- /dev/null +++ b/graphs/breathfirstsearch.go @@ -0,0 +1,72 @@ +package graphs + +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/graphs/depthfirstsearch.go b/graphs/depthfirstsearch.go new file mode 100644 index 0000000..6f0003c --- /dev/null +++ b/graphs/depthfirstsearch.go @@ -0,0 +1,72 @@ +package graphs + +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 dfs(start, end int, nodes []int, edges [][]bool) ([]int, bool) { + var route []int + var stack []int + startIdx := getIdx(start, nodes) + stack = append(stack, startIdx) + for len(stack) > 0 { + now := stack[len(stack)-1] + route = append(route, nodes[now]) + if len(stack) > 1 { + stack = stack[:len(stack)-1] + } else { + stack = stack[:len(stack)-1] + } + for i := 0; i < len(edges[now]); i++ { + if edges[now][i] && notExist(i, stack) { + stack = append(stack, i) + } + edges[now][i] = false + edges[i][now] = false + } + if route[len(route)-1] == end { + return route, true + } + } + return nil, 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 + route, _ := dfs(start, end, nodes, edges) + fmt.Println(route) +} diff --git a/graphs/floydwarshall.go b/graphs/floydwarshall.go new file mode 100644 index 0000000..4fe0807 --- /dev/null +++ b/graphs/floydwarshall.go @@ -0,0 +1,64 @@ +// Floyd-Warshall algorithm +// https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm + +package graphs + +import ( + "math" + "fmt" +) + +// Defining matrix to use 2d array easier +type Matrix [][]float64 + +// Defining maximum value. If two vertices share this value, it means they are not connected +var maxValue = math.Inf(1) + +// Returns all pair's shortest path using Floyd Warshall algorithm +func FloydWarshall(graph Matrix) Matrix { + // If graph is empty or width != height, returns nil + if len(graph) == 0 || len(graph) != len(graph[0]) { + return nil + } + + numVertecies := len(graph) + + // Initializing result matrix and filling it up with same values as given graph + result := make(Matrix, numVertecies) + + for i := 0; i < numVertecies; i++ { + result[i] = make([]float64, numVertecies) + for j := 0; j < numVertecies; j++ { + result[i][j] = graph[i][j] + } + } + + // Running over the result matrix and following the algorithm + for k := 0; k < numVertecies; k++ { + for i := 0; i < numVertecies; i++ { + for j := 0; j < numVertecies; j++ { + // If there is a less costly path from i to j node, remembering it + if result[i][j] > result[i][k]+result[k][j] { + result[i][j] = result[i][k] + result[k][j] + } + } + } + } + + return result +} + +func main() { + var graph Matrix + graph = Matrix{{0, maxValue, -2, maxValue}, + {4, 0, 3, maxValue}, + {maxValue, maxValue, 0, 2}, + {maxValue, -1, maxValue, 0}} + + result := FloydWarshall(graph) + + //Print result + for i := 0; i < len(result); i++ { + fmt.Printf("%4g\n", result[i]) + } + } From 6214dbc6131556e185bbff17b2e4d418ad17acba Mon Sep 17 00:00:00 2001 From: Rahul7171 <69434755+Rahul7171@users.noreply.github.com> Date: Sun, 27 Dec 2020 23:39:28 +0530 Subject: [PATCH 7/7] Add files via upload --- .../roman-to-integer/roman_to_integer.go | 25 ++++++++++++++++ .../roman-to-integer/roman_to_integer_test.go | 29 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 conversions/roman-to-integer/roman_to_integer.go create mode 100644 conversions/roman-to-integer/roman_to_integer_test.go diff --git a/conversions/roman-to-integer/roman_to_integer.go b/conversions/roman-to-integer/roman_to_integer.go new file mode 100644 index 0000000..b9601e7 --- /dev/null +++ b/conversions/roman-to-integer/roman_to_integer.go @@ -0,0 +1,25 @@ +/* +This algorithm will convert a standard roman number to an integer +https://en.wikipedia.org/wiki/Roman_numerals +Function receives a string as a roman number and outputs an integer +Maximum output will be 3999 +Only standard form is supported +*/ +package conversions + +var romans = map[string]int{"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000} + +func RomanToInteger(roman string) int { + total := 0 + holder := 0 + for holder < len(roman) { + if holder+1 < len(roman) && (romans[string(roman[holder])] < romans[string(roman[holder+1])]) { + total += romans[string(roman[holder+1])] - romans[string(roman[holder])] + holder += 2 + } else { + total += romans[string(roman[holder])] + holder++ + } + } + return total +} diff --git a/conversions/roman-to-integer/roman_to_integer_test.go b/conversions/roman-to-integer/roman_to_integer_test.go new file mode 100644 index 0000000..9923e59 --- /dev/null +++ b/conversions/roman-to-integer/roman_to_integer_test.go @@ -0,0 +1,29 @@ +package conversions + +import "testing" + +type romanToIntegerConversionTest struct { + input string + expected int + name string +} + +var romanToIntegerTests = []romanToIntegerConversionTest{ + {input: "DCCLXXXIX", expected: 789, name: "DCCLXXXIX-789"}, + {input: "MLXVI", expected: 1066, name: "MLXVI-1066"}, + {input: "MCMXVIII", expected: 1918, name: "MCMXVIII-1918"}, + {input: "V", expected: 5, name: "V-5"}, +} + +func TestRomanToInteger(t *testing.T) { + + for _, test := range romanToIntegerTests { + convertedValue := RomanToInteger(test.input) + if convertedValue != test.expected { + t.Errorf( + "roman to integer test %s failed. expected '%d' but got '%d'", + test.name, test.expected, convertedValue, + ) + } + } +}