algorithmable 0.11.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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