algorithmable 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23dff715f8d8ae5e91a4e738ec6fe52f9da12fe7
4
- data.tar.gz: dbfa9eb077c85ba9957f10edbb99513e793ca495
3
+ metadata.gz: 484ef490b06d5cd0c396fc76651dec47edd406c8
4
+ data.tar.gz: ea9ba9dd9e2e6cbc886e3bf1a3022eda64badb21
5
5
  SHA512:
6
- metadata.gz: d5a1aedb5222032d612c3037a91c94c303a1f4cfe955d752b97d6e4543d210f444fc5d01a203fe60c91dd969f4ed453a8e7bc5055264906bbbc062fc51f6ab4d
7
- data.tar.gz: 784476ad38e96e828f2360f6272ab4d7b2b9d176446183257592d9595cdf769c85f59994a6ce23437537acd9ad1620f7c02b299fea43fcda3a7a648916d4ec6d
6
+ metadata.gz: d022c89e7953ee18649511d595c126892d7eb8d1c3bedfd21bdcc7804caf2cf592c7ecd8d019a3ec12555728ba17e541170b0b660d7368a879d5ff27961c18bc
7
+ data.tar.gz: 4497b73d3190fa9492a8c3966a50c2aa110dafd5e80656218c275d58ece61462859f4598c15a8c8441aa493afef371e09cc9f2b4bd183fb77ba760d98e472e69
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  /coverage
14
14
  /rspec.xml
15
15
  /bin
16
+ /debugger.*
data/README.md CHANGED
@@ -12,6 +12,7 @@ Library also contains solutions for several puzzles solved by implemented algori
12
12
  ## Data Structures
13
13
 
14
14
  - Bag (primitive collection without ability to delete elements)
15
+ - Singly Linked List
15
16
  - Doubly Linked List
16
17
  - Deque (double-ended queue)
17
18
  - Queue (FIFO)
@@ -19,6 +20,7 @@ Library also contains solutions for several puzzles solved by implemented algori
19
20
  - Ordered Symbol Table BST. Implementation using Unbalanced Binary Search Tree.
20
21
  - Minimum Priority Queue
21
22
  - Maximum Priority Queue
23
+ - Ordered Symbol Table
22
24
 
23
25
  ## Graphs
24
26
 
@@ -37,13 +39,18 @@ Library also contains solutions for several puzzles solved by implemented algori
37
39
 
38
40
  - Bubble sort
39
41
  - Merge sort
40
- - Heaport ( Binary Heap )
42
+ - Heapsort ( Binary Heap )
41
43
 
42
44
  ## Algorithms
43
45
 
44
46
  - Levenshtein Distance algorithm (http://www.levenshtein.net)
45
47
  - Lawrence Philips' Metaphone Algorithm (http://aspell.net/metaphone)
46
48
 
49
+ ## Puzzles
50
+
51
+ - Shunting-yard algorithm ( Dijkstras two stacks algorithm )
52
+ - Josephus problem
53
+
47
54
  # Usage
48
55
 
49
56
  It is always better to check unit tests in order to understand how things going on.
@@ -0,0 +1,98 @@
1
+ module Algorithmable
2
+ module Cups
3
+ module Primitives
4
+ # this module contains a lot of C style code. It is done intentionally.
5
+ # All the methods avoiding using already existent algorithms in Ruby.
6
+ # Algorithms/solutions should be implemented in place
7
+
8
+ def replace_space_chars(string, expression = '%20')
9
+ return unless string
10
+ space_count = 0
11
+ length = string.length
12
+ replacement = expression.chars.reverse.freeze
13
+ length.times { |i| space_count += 1 if string[i] == ' ' }
14
+ new_length = length + space_count * 2
15
+ chars = Array.new(new_length, ?\x00)
16
+
17
+ (0..length.pred).to_a.reverse_each do |i|
18
+ if string[i] == ' '
19
+ replacement.each_with_index do |char, index|
20
+ j = index + 1
21
+ chars[new_length - j] = char
22
+ end
23
+ new_length = new_length - replacement.length
24
+ else
25
+ new_length -= 1
26
+ chars[new_length] = string[i]
27
+ end
28
+ end
29
+
30
+ chars.join
31
+ end
32
+
33
+ def chars_is_uniq?(string)
34
+ return unless string
35
+ map = Array.new 127, false
36
+ string.chars.each do |char|
37
+ return false if map[char.ord]
38
+ map[char.ord] = true
39
+ end
40
+ end
41
+
42
+ def reverse_string(string)
43
+ return unless string
44
+ chars = string.chars
45
+ reversed = ''
46
+ string.size.times { reversed << chars.pop }
47
+ reversed
48
+ end
49
+
50
+ def remove_duplicated_chars(chars = [])
51
+ return if chars.empty? || chars.size < 2
52
+ array_tail = 1
53
+
54
+ chars.size.times do |cur_char_index|
55
+ next unless cur_char_index.nonzero?
56
+ prev_char_index = 0
57
+
58
+ while prev_char_index < array_tail
59
+ break if chars[cur_char_index] == chars[prev_char_index]
60
+ prev_char_index += 1
61
+ end
62
+
63
+ if prev_char_index == array_tail
64
+ chars[array_tail] = chars[cur_char_index]
65
+ array_tail += 1
66
+ end
67
+ end
68
+
69
+ # trim all after new tail
70
+ chars[0...array_tail]
71
+ end
72
+
73
+ def find_cycled_node(root)
74
+ return unless root.next or root.next.next
75
+ slow = root
76
+ fast = root
77
+
78
+ until fast.next.nil?
79
+ slow = slow.next
80
+ fast = fast.next.next
81
+ break if slow == fast
82
+ end
83
+
84
+ # return, no cycle
85
+ return if fast.next.nil?
86
+
87
+ slow = root
88
+ until slow == fast
89
+ slow = slow.next
90
+ fast = fast.next
91
+ end
92
+
93
+ # at this point return value is a node which is tail pointing to.
94
+ fast
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,5 @@
1
+ module Algorithmable
2
+ module Cups
3
+ autoload :Primitives, 'algorithmable/cups/primitives'
4
+ end
5
+ end
@@ -0,0 +1,92 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module LinkedList
4
+ class Base
5
+ attr_reader :size, :front
6
+
7
+ def initialize(collection = [])
8
+ @front = nil
9
+ @back = nil
10
+ @size = 0
11
+ collection.each { |item| push_front item }
12
+ end
13
+
14
+ def empty?
15
+ 0 == size
16
+ end
17
+
18
+ def clear!
19
+ @front = nil
20
+ @back = nil
21
+ @size = 0
22
+ end
23
+
24
+ def peek_front
25
+ @front && @front.item
26
+ end
27
+
28
+ def peek_back
29
+ @back && @back.item
30
+ end
31
+
32
+ def include?(item)
33
+ !search(item).nil?
34
+ end
35
+
36
+ def push_back(_item)
37
+ fail NotImplementedError
38
+ end
39
+
40
+ def push_front(_item)
41
+ fail NotImplementedError
42
+ end
43
+
44
+ def pop_back
45
+ fail NotImplementedError
46
+ end
47
+
48
+ def pop_front
49
+ fail NotImplementedError
50
+ end
51
+
52
+ def delete(_item)
53
+ fail NotImplementedError
54
+ end
55
+
56
+ def reverse
57
+ fail NotImplementedError
58
+ end
59
+
60
+ def merge(_other_list)
61
+ fail NotImplementedError
62
+ end
63
+
64
+ private
65
+
66
+ def search(item)
67
+ return if empty?
68
+ node = @front
69
+ while node
70
+ break if node.item == item
71
+ node = node.next
72
+ end
73
+ node
74
+ end
75
+
76
+ def each(&block)
77
+ nodes = []
78
+ node = @front
79
+ until node.nil?
80
+ nodes << node
81
+ node = node.next
82
+ end
83
+ nodes.each(&block)
84
+ end
85
+
86
+ def new_node(_item, *_args)
87
+ fail NotImplementedError
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,86 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module LinkedList
4
+ class Doubly < Base
5
+ class Node
6
+ attr_accessor :item, :prev, :next
7
+
8
+ def initialize(item, prev_pointer = nil, next_pointer = nil)
9
+ @item = item
10
+ @prev = prev_pointer
11
+ @next = next_pointer
12
+ end
13
+ end
14
+
15
+ private_constant :Node
16
+
17
+ def push_front(item)
18
+ prev_front = @front
19
+ node = new_node item, nil, prev_front
20
+ @front = node
21
+
22
+ if prev_front
23
+ prev_front.prev = node
24
+ else
25
+ @back = node
26
+ end
27
+
28
+ @size += 1
29
+ item
30
+ end
31
+
32
+ def push_back(item)
33
+ prev_back = @back
34
+ node = Node.new item, prev_back, nil
35
+ @back = node
36
+
37
+ if prev_back
38
+ prev_back.next = node
39
+ else
40
+ @front = node
41
+ end
42
+
43
+ @size += 1
44
+ item
45
+ end
46
+
47
+ def pop_front
48
+ delete peek_front
49
+ end
50
+
51
+ def pop_back
52
+ delete peek_back
53
+ end
54
+
55
+ def delete(item)
56
+ node = search(item)
57
+ return unless node
58
+
59
+ prev_node = node.prev
60
+ next_node = node.next
61
+
62
+ if prev_node.nil?
63
+ @front = next_node
64
+ else
65
+ prev_node.next = next_node
66
+ end
67
+
68
+ if next_node.nil?
69
+ @back = prev_node
70
+ else
71
+ next_node.prev = prev_node
72
+ end
73
+
74
+ @size -= 1
75
+ item
76
+ end
77
+
78
+ private
79
+
80
+ def new_node(item, prev_pointer = nil, next_pinter = nil)
81
+ Node.new item, prev_pointer, next_pinter
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,127 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module LinkedList
4
+ class Singly < Base
5
+ class Node
6
+ attr_accessor :item, :next
7
+
8
+ def initialize(item, next_pointer = nil)
9
+ @item = item
10
+ @next = next_pointer
11
+ end
12
+ end
13
+
14
+ private_constant :Node
15
+
16
+ def push_front(obj)
17
+ node = new_node(obj)
18
+ if @front
19
+ node.next = @front
20
+ @front = node
21
+ else
22
+ @front = node
23
+ @back = @front
24
+ end
25
+ @size += 1
26
+ obj
27
+ end
28
+
29
+ def push_back(obj)
30
+ node = new_node(obj)
31
+ if @back
32
+ @back.next = node
33
+ @back = node
34
+ else
35
+ @front = node
36
+ @back = @front
37
+ end
38
+ @size += 1
39
+ obj
40
+ end
41
+
42
+ def pop_front
43
+ return unless @front
44
+ node = @front
45
+
46
+ if @front == @back
47
+ clear!
48
+ else
49
+ @front = @front.next
50
+ @size -= 1
51
+ end
52
+
53
+ node.item
54
+ end
55
+
56
+ def pop_back
57
+ return unless @back
58
+ node = @back
59
+ if @front == @back
60
+ clear!
61
+ else
62
+ prev = @front
63
+ prev = prev.next while prev.next != @back
64
+ @back = prev
65
+ @back.next = nil
66
+ @size -= 1
67
+ end
68
+ node.item
69
+ end
70
+
71
+ def delete(item)
72
+ tmp_node = @front
73
+ prev_node = nil
74
+
75
+ until tmp_node.nil?
76
+ if tmp_node.item == item
77
+ if tmp_node == @front
78
+ next_node = @front.next
79
+ @back = next_node if @front == @back
80
+ @front = next_node
81
+ @size -= 1
82
+ else
83
+ prev_node.next = tmp_node.next
84
+ @back = prev_node if tmp_node == @back
85
+ @size -= 1
86
+ end
87
+ return true
88
+ else
89
+ prev_node = tmp_node
90
+ end
91
+
92
+ tmp_node = tmp_node.next
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def reverse_imp(root)
99
+ return root if root.nil? || root.next.nil?
100
+ node = reverse_imp(root.next)
101
+ root.next.next = root
102
+ root.next = nil
103
+ node
104
+ end
105
+
106
+ def remove_next(prev)
107
+ if prev.nil?
108
+ pop_front
109
+ elsif prev.next == @back
110
+ @back = prev
111
+ @back.next = nil
112
+ @size -= 1
113
+ elsif prev == @back
114
+ return
115
+ else
116
+ prev.next = prev.next.next
117
+ @size -= 1
118
+ end
119
+ end
120
+
121
+ def new_node(item, next_pinter = nil)
122
+ Node.new item, next_pinter
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -1,101 +1,19 @@
1
1
  module Algorithmable
2
2
  module DataStructs
3
- class LinkedList
4
- include Enumerable
5
- attr_reader :length
3
+ module LinkedList
4
+ autoload :Base, 'algorithmable/data_structs/linked_list/base'
5
+ autoload :Singly, 'algorithmable/data_structs/linked_list/singly'
6
+ autoload :Doubly, 'algorithmable/data_structs/linked_list/doubly'
6
7
 
7
- def initialize
8
- @head = nil
9
- @tail = nil
10
- @length = 0
11
- @op_counter = 0
12
- end
13
-
14
- def unshift(data)
15
- link_head_node data
16
- end
17
-
18
- def push(data)
19
- link_tail_node data
20
- end
21
-
22
- def first
23
- @head ? @head.dup : fail_index_error
24
- end
25
-
26
- def last
27
- @tail ? @tail.dup : fail_index_error
28
- end
29
-
30
- def each(&block)
31
- next_node = @head
32
- nodes = []
33
- while next_node
34
- nodes << next_node
35
- next_node = next_node.succ
36
- end
37
- nodes.each(&block)
38
- end
39
-
40
- private
41
-
42
- def link_head_node(data)
43
- prev_head = @head
44
- node = make_node data, nil, prev_head
45
- @head = node
46
-
47
- if prev_head
48
- prev_head.pred = node
49
- else
50
- @tail = node
51
- end
8
+ private_constant :Base
52
9
 
53
- bump_length!
54
- bump_op_counter!
10
+ def new_singly_linked_list(collection = [])
11
+ Singly.new collection
55
12
  end
56
13
 
57
- def link_tail_node(data)
58
- prev_tail = @tail
59
- node = make_node data, prev_tail, nil
60
- @tail = node
61
-
62
- if prev_tail
63
- prev_tail.succ = node
64
- else
65
- @head = node
66
- end
67
-
68
- bump_length!
69
- bump_op_counter!
70
- end
71
-
72
- def make_node(data, pred = nil, succ = nil)
73
- Node.new data, pred, succ
74
- end
75
-
76
- def bump_length!
77
- @length = @length.next
78
- end
79
-
80
- def bump_op_counter!
81
- @op_counter = @op_counter.next
82
- end
83
-
84
- def fail_index_error(message = nil)
85
- fail IndexError, message
86
- end
87
-
88
- class Node
89
- attr_accessor :pred, :succ
90
- attr_reader :data
91
-
92
- def initialize(data, pred = nil, succ = nil)
93
- @data = data
94
- @pred = pred
95
- @succ = succ
96
- end
14
+ def new_doubly_linked_list(collection = [])
15
+ Doubly.new collection
97
16
  end
98
- private_constant :Node
99
17
  end
100
18
  end
101
19
  end
@@ -8,14 +8,12 @@ module Algorithmable
8
8
  autoload :OrderedSymbolTable, 'algorithmable/data_structs/ordered_symbol_table'
9
9
  autoload :Heap, 'algorithmable/data_structs/heap'
10
10
 
11
+ include LinkedList
12
+
11
13
  def new_bag
12
14
  Bag.new
13
15
  end
14
16
 
15
- def new_linked_list
16
- LinkedList.new
17
- end
18
-
19
17
  def new_fifo_queue
20
18
  Queue.new
21
19
  end
@@ -28,16 +26,16 @@ module Algorithmable
28
26
  OrderedSymbolTable.new(key_type, value_type)
29
27
  end
30
28
 
31
- def new_max_priority_heap(collection = [])
32
- Heap::Max.new(collection)
29
+ def new_priority_queue(collection, &block)
30
+ Heap::Max.new(collection, &block)
33
31
  end
34
32
 
35
- alias_method :new_max_priority_queue, :new_max_priority_heap
33
+ def new_max_priority_queue(collection = [])
34
+ Heap::Max.new(collection)
35
+ end
36
36
 
37
- def new_min_priority_heap(collection = [])
37
+ def new_min_priority_queue(collection = [])
38
38
  Heap::Min.new(collection)
39
39
  end
40
-
41
- alias_method :new_min_priority_queue, :new_min_priority_heap
42
40
  end
43
41
  end
@@ -8,7 +8,7 @@ module Algorithmable
8
8
  end
9
9
 
10
10
  def initialize(collection = [])
11
- @heap = new_min_priority_heap collection
11
+ @heap = new_min_priority_queue collection
12
12
  end
13
13
 
14
14
  def sort
@@ -1,3 +1,3 @@
1
1
  module Algorithmable
2
- VERSION = '0.11.0'
2
+ VERSION = '0.13.0'
3
3
  end
data/lib/algorithmable.rb CHANGED
@@ -12,6 +12,7 @@ module Algorithmable
12
12
  autoload :Graphs, 'algorithmable/graphs'
13
13
  autoload :Puzzles, 'algorithmable/puzzles'
14
14
  autoload :LevenshteinDistance, 'algorithmable/levenshtein_distance'
15
+ autoload :Cups, 'algorithmable/cups'
15
16
 
16
17
  class << self
17
18
  def logger
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algorithmable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Lishtaba
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -140,6 +140,8 @@ files:
140
140
  - algorithmable.gemspec
141
141
  - cucumber.yml
142
142
  - lib/algorithmable.rb
143
+ - lib/algorithmable/cups.rb
144
+ - lib/algorithmable/cups/primitives.rb
143
145
  - lib/algorithmable/data_structs.rb
144
146
  - lib/algorithmable/data_structs/bag.rb
145
147
  - lib/algorithmable/data_structs/deque.rb
@@ -148,6 +150,9 @@ files:
148
150
  - lib/algorithmable/data_structs/heap/max.rb
149
151
  - lib/algorithmable/data_structs/heap/min.rb
150
152
  - lib/algorithmable/data_structs/linked_list.rb
153
+ - lib/algorithmable/data_structs/linked_list/base.rb
154
+ - lib/algorithmable/data_structs/linked_list/doubly.rb
155
+ - lib/algorithmable/data_structs/linked_list/singly.rb
151
156
  - lib/algorithmable/data_structs/ordered_symbol_table.rb
152
157
  - lib/algorithmable/data_structs/queue.rb
153
158
  - lib/algorithmable/data_structs/stack.rb