algorithmable 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/algorithmable/data_structs/bag.rb +0 -2
- data/lib/algorithmable/data_structs/deque.rb +112 -0
- data/lib/algorithmable/data_structs/linked_list.rb +93 -5
- data/lib/algorithmable/data_structs/queue.rb +10 -66
- data/lib/algorithmable/data_structs/stack.rb +30 -0
- data/lib/algorithmable/data_structs.rb +16 -4
- data/lib/algorithmable/errors.rb +5 -0
- data/lib/algorithmable/graphs/traversals/breadth_first.rb +4 -5
- data/lib/algorithmable/graphs/undirected.rb +1 -1
- data/lib/algorithmable/puzzles/dijkstras_two_stacks.rb +50 -0
- data/lib/algorithmable/puzzles/josephus_problem.rb +25 -0
- data/lib/algorithmable/puzzles.rb +10 -0
- data/lib/algorithmable/sort/binary_heap.rb +23 -0
- data/lib/algorithmable/sort.rb +1 -0
- data/lib/algorithmable/version.rb +1 -1
- data/lib/algorithmable.rb +2 -0
- metadata +9 -4
- data/lib/algorithmable/data_structs/linked_list/impl.rb +0 -102
- data/lib/algorithmable/data_structs/linked_list/node.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ae7569f2df39cfefa86f0a46fafd1e1b91199d3
|
4
|
+
data.tar.gz: ebb4364c7e699846eef95bd47e09c26b8dc721f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cae4039f94a406279f630ece5f363e05f9dd9c406152e9b19fdcf8adedf427a9ad8c21a569ba14a44f0e909c1980249e7d907b25e592c8129db10135f9797b8
|
7
|
+
data.tar.gz: e2827ed66df194ee618724277b55c986c371dd8cd638632ccff264b3a81bb3853c1aa935cf7811ade5fa20aee47c65cbf2060d5a79c215d288f469fd322e4108
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module DataStructs
|
3
|
+
class Deque
|
4
|
+
include Enumerable
|
5
|
+
include Algorithmable::Errors
|
6
|
+
|
7
|
+
Node = Struct.new(:prev, :next, :item)
|
8
|
+
attr_reader :size
|
9
|
+
|
10
|
+
def initialize(collection = [])
|
11
|
+
@front = nil
|
12
|
+
@back = nil
|
13
|
+
@size = 0
|
14
|
+
collection.each { |item| push_back(item) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def empty?
|
18
|
+
0 == size
|
19
|
+
end
|
20
|
+
|
21
|
+
def clear
|
22
|
+
@front = nil
|
23
|
+
@back = nil
|
24
|
+
@size = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def peek_front
|
28
|
+
@front && @front.item
|
29
|
+
end
|
30
|
+
|
31
|
+
def peek_back
|
32
|
+
@back && @back.item
|
33
|
+
end
|
34
|
+
|
35
|
+
def push_front(obj)
|
36
|
+
node = Node.new(nil, nil, obj)
|
37
|
+
if @front
|
38
|
+
node.next = @front
|
39
|
+
@front.prev = node
|
40
|
+
@front = node
|
41
|
+
else
|
42
|
+
@front = node
|
43
|
+
@back = @front
|
44
|
+
end
|
45
|
+
@size += 1
|
46
|
+
obj
|
47
|
+
end
|
48
|
+
|
49
|
+
def push_back(obj)
|
50
|
+
node = Node.new(nil, nil, obj)
|
51
|
+
if @back
|
52
|
+
node.prev = @back
|
53
|
+
@back.next = node
|
54
|
+
@back = node
|
55
|
+
else
|
56
|
+
@front = node
|
57
|
+
@back = @front
|
58
|
+
end
|
59
|
+
@size += 1
|
60
|
+
obj
|
61
|
+
end
|
62
|
+
|
63
|
+
def pop_front
|
64
|
+
fail NoSuchElementError unless @front
|
65
|
+
node = @front
|
66
|
+
if 1 == @size
|
67
|
+
clear
|
68
|
+
return node.item
|
69
|
+
else
|
70
|
+
@front.next.prev = nil
|
71
|
+
@front = @front.next
|
72
|
+
end
|
73
|
+
@size -= 1
|
74
|
+
node.item
|
75
|
+
end
|
76
|
+
|
77
|
+
def pop_back
|
78
|
+
fail NoSuchElementError unless @back
|
79
|
+
node = @back
|
80
|
+
if @size == 1
|
81
|
+
clear
|
82
|
+
return node.item
|
83
|
+
else
|
84
|
+
@back.prev.next = nil
|
85
|
+
@back = @back.prev
|
86
|
+
end
|
87
|
+
@size -= 1
|
88
|
+
node.item
|
89
|
+
end
|
90
|
+
|
91
|
+
# represent fifo iterator
|
92
|
+
def each
|
93
|
+
return unless @front
|
94
|
+
node = @front
|
95
|
+
while node
|
96
|
+
yield node.item
|
97
|
+
node = node.next
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# represent lifo iterator
|
102
|
+
def reverse_each
|
103
|
+
return unless @back
|
104
|
+
node = @back
|
105
|
+
while node
|
106
|
+
yield node.item
|
107
|
+
node = node.prev
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,11 +1,99 @@
|
|
1
1
|
module Algorithmable
|
2
2
|
module DataStructs
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
class LinkedList
|
4
|
+
include Enumerable
|
5
|
+
attr_reader :length
|
6
6
|
|
7
|
-
def
|
8
|
-
|
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
|
52
|
+
|
53
|
+
bump_length!
|
54
|
+
bump_op_counter!
|
55
|
+
end
|
56
|
+
|
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
|
9
97
|
end
|
10
98
|
end
|
11
99
|
end
|
@@ -1,84 +1,28 @@
|
|
1
|
-
require 'monitor'
|
2
|
-
|
3
1
|
module Algorithmable
|
4
2
|
module DataStructs
|
5
3
|
class Queue
|
4
|
+
include Algorithmable::Errors
|
6
5
|
include Enumerable
|
7
|
-
|
8
|
-
attr_reader :size
|
9
|
-
|
10
|
-
SEPARATOR = ':'
|
6
|
+
extend Forwardable
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
@first = nil
|
16
|
-
@last = nil
|
17
|
-
@size = 0
|
18
|
-
super
|
19
|
-
end
|
8
|
+
def_delegators :@imp, :empty?, :size, :each
|
20
9
|
|
21
|
-
def
|
22
|
-
|
10
|
+
def initialize(collection = [])
|
11
|
+
@imp = Deque.new collection
|
23
12
|
end
|
24
13
|
|
25
14
|
def peek
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
15
|
+
peek_value = @imp.peek_front
|
16
|
+
fail NoSuchElementError unless peek_value
|
17
|
+
peek_value
|
30
18
|
end
|
31
19
|
|
32
20
|
def enqueue(item)
|
33
|
-
|
34
|
-
old_last = @last
|
35
|
-
@last = Node.new item
|
36
|
-
@last.succ = nil
|
37
|
-
@first = @last if empty?
|
38
|
-
old_last.succ = @last unless empty?
|
39
|
-
@size = @size.next
|
40
|
-
end
|
21
|
+
@imp.push_back(item)
|
41
22
|
end
|
42
23
|
|
43
24
|
def dequeue
|
44
|
-
|
45
|
-
fail NoSuchElementError if empty?
|
46
|
-
item = @first.item
|
47
|
-
@first = @first.succ
|
48
|
-
@size = @size.pred
|
49
|
-
@last = nil if empty?
|
50
|
-
item
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_s
|
55
|
-
synchronize do
|
56
|
-
to_a.join SEPARATOR
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def each(&block)
|
61
|
-
synchronize do
|
62
|
-
(@first || []).each(&block)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class Node
|
67
|
-
attr_accessor :succ, :item
|
68
|
-
|
69
|
-
def initialize(item)
|
70
|
-
@item = item
|
71
|
-
@succ = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_s
|
75
|
-
@item.to_s
|
76
|
-
end
|
77
|
-
|
78
|
-
def each(&block)
|
79
|
-
yield self
|
80
|
-
@succ.each(&block) if @succ
|
81
|
-
end
|
25
|
+
@imp.pop_front
|
82
26
|
end
|
83
27
|
end
|
84
28
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module DataStructs
|
3
|
+
class Stack
|
4
|
+
include Algorithmable::Errors
|
5
|
+
include Enumerable
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@imp, :empty?, :size, :each
|
9
|
+
|
10
|
+
def initialize(collection = [])
|
11
|
+
@imp = Deque.new
|
12
|
+
collection.each { |item| @imp.push_front item }
|
13
|
+
end
|
14
|
+
|
15
|
+
def peek
|
16
|
+
peek_value = @imp.peek_front
|
17
|
+
fail NoSuchElementError unless peek_value
|
18
|
+
peek_value
|
19
|
+
end
|
20
|
+
|
21
|
+
def push(item)
|
22
|
+
@imp.push_front(item)
|
23
|
+
end
|
24
|
+
|
25
|
+
def pop
|
26
|
+
@imp.pop_front
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,13 +1,25 @@
|
|
1
1
|
module Algorithmable
|
2
2
|
module DataStructs
|
3
|
+
autoload :Deque, 'algorithmable/data_structs/deque'
|
3
4
|
autoload :Bag, 'algorithmable/data_structs/bag'
|
4
5
|
autoload :LinkedList, 'algorithmable/data_structs/linked_list'
|
5
6
|
autoload :Queue, 'algorithmable/data_structs/queue'
|
7
|
+
autoload :Stack, 'algorithmable/data_structs/stack'
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def new_bag
|
10
|
+
Bag.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_linked_list
|
14
|
+
LinkedList.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_fifo_queue
|
18
|
+
Queue.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_lifo_queue
|
22
|
+
Stack.new
|
11
23
|
end
|
12
24
|
end
|
13
25
|
end
|
@@ -38,11 +38,10 @@ module Algorithmable
|
|
38
38
|
until queue.empty?
|
39
39
|
next_vertex = queue.deq
|
40
40
|
graph.adjacency(next_vertex).each do |neighbour_vertex|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
41
|
+
next if visited? neighbour_vertex
|
42
|
+
@edge_to[neighbour_vertex] = next_vertex
|
43
|
+
@visited[neighbour_vertex] = true
|
44
|
+
queue.enq neighbour_vertex
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Puzzles
|
3
|
+
class DijkstrasTwoStacks
|
4
|
+
include Algorithmable::DataStructs
|
5
|
+
|
6
|
+
MATH_OPS = %w(sqrt cos sin tan atan2 log log2 log10)
|
7
|
+
ARITHMETICAL_OPS = %w(+ - * /)
|
8
|
+
OPS = ARITHMETICAL_OPS + MATH_OPS
|
9
|
+
OPEN_EXP = '('
|
10
|
+
CLOSE_EXP = ')'
|
11
|
+
|
12
|
+
def initialize(expression)
|
13
|
+
@expression = expression
|
14
|
+
end
|
15
|
+
|
16
|
+
def solve
|
17
|
+
operations = new_lifo_queue
|
18
|
+
values = new_lifo_queue
|
19
|
+
parse_expression(operations, values)
|
20
|
+
values.pop
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse_expression(operations, values)
|
26
|
+
@expression.split.each do |char|
|
27
|
+
if OPEN_EXP == char
|
28
|
+
# noop
|
29
|
+
elsif OPS.include?(char)
|
30
|
+
operations.push char
|
31
|
+
elsif CLOSE_EXP == char
|
32
|
+
operation = operations.pop
|
33
|
+
value = values.pop
|
34
|
+
compute operation, value, values
|
35
|
+
else
|
36
|
+
values.push Float(char)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def compute(operation, value, values_stack)
|
42
|
+
if MATH_OPS.include? operation
|
43
|
+
values_stack.push Math.send(operation, value)
|
44
|
+
else
|
45
|
+
values_stack.push values_stack.pop.send(operation, value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Puzzles
|
3
|
+
class JosephusProblem
|
4
|
+
include Algorithmable::DataStructs
|
5
|
+
|
6
|
+
def initialize(prisoners, every)
|
7
|
+
@prisoners = prisoners
|
8
|
+
@every = every
|
9
|
+
end
|
10
|
+
|
11
|
+
def solve
|
12
|
+
queue = new_fifo_queue
|
13
|
+
@prisoners.times { |item| queue.enqueue(item) }
|
14
|
+
positions = []
|
15
|
+
until queue.empty?
|
16
|
+
(@every - 1).times do
|
17
|
+
queue.enqueue queue.dequeue
|
18
|
+
end
|
19
|
+
positions << queue.dequeue
|
20
|
+
end
|
21
|
+
positions
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Puzzles
|
3
|
+
autoload :JosephusProblem, 'algorithmable/puzzles/josephus_problem'
|
4
|
+
autoload :DijkstrasTwoStacks, 'algorithmable/puzzles/dijkstras_two_stacks'
|
5
|
+
|
6
|
+
def new_josephus_problem(prisoners, every)
|
7
|
+
JosephusProblem.new(prisoners, every)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Sort
|
3
|
+
class BinaryHeap
|
4
|
+
def self.sort(collection)
|
5
|
+
new.sort(collection)
|
6
|
+
end
|
7
|
+
|
8
|
+
def sort(collection)
|
9
|
+
fail NotImplementedError, collection
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def swim(node)
|
15
|
+
fail NotImplementedError, node
|
16
|
+
end
|
17
|
+
|
18
|
+
def sink(node)
|
19
|
+
fail NotImplementedError, node
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/algorithmable/sort.rb
CHANGED
data/lib/algorithmable.rb
CHANGED
@@ -5,9 +5,11 @@ require 'pathname'
|
|
5
5
|
require 'English'
|
6
6
|
|
7
7
|
module Algorithmable
|
8
|
+
autoload :Errors, 'algorithmable/errors'
|
8
9
|
autoload :Sort, 'algorithmable/sort'
|
9
10
|
autoload :DataStructs, 'algorithmable/data_structs'
|
10
11
|
autoload :Graphs, 'algorithmable/graphs'
|
12
|
+
autoload :Puzzles, 'algorithmable/puzzles'
|
11
13
|
|
12
14
|
class << self
|
13
15
|
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.
|
4
|
+
version: 0.7.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
|
+
date: 2016-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,17 +142,22 @@ files:
|
|
142
142
|
- lib/algorithmable.rb
|
143
143
|
- lib/algorithmable/data_structs.rb
|
144
144
|
- lib/algorithmable/data_structs/bag.rb
|
145
|
+
- lib/algorithmable/data_structs/deque.rb
|
145
146
|
- lib/algorithmable/data_structs/linked_list.rb
|
146
|
-
- lib/algorithmable/data_structs/linked_list/impl.rb
|
147
|
-
- lib/algorithmable/data_structs/linked_list/node.rb
|
148
147
|
- lib/algorithmable/data_structs/queue.rb
|
148
|
+
- lib/algorithmable/data_structs/stack.rb
|
149
|
+
- lib/algorithmable/errors.rb
|
149
150
|
- lib/algorithmable/graphs.rb
|
150
151
|
- lib/algorithmable/graphs/traversals.rb
|
151
152
|
- lib/algorithmable/graphs/traversals/breadth_first.rb
|
152
153
|
- lib/algorithmable/graphs/traversals/depth_first.rb
|
153
154
|
- lib/algorithmable/graphs/traversals/errors.rb
|
154
155
|
- lib/algorithmable/graphs/undirected.rb
|
156
|
+
- lib/algorithmable/puzzles.rb
|
157
|
+
- lib/algorithmable/puzzles/dijkstras_two_stacks.rb
|
158
|
+
- lib/algorithmable/puzzles/josephus_problem.rb
|
155
159
|
- lib/algorithmable/sort.rb
|
160
|
+
- lib/algorithmable/sort/binary_heap.rb
|
156
161
|
- lib/algorithmable/sort/bubble.rb
|
157
162
|
- lib/algorithmable/sort/merge.rb
|
158
163
|
- lib/algorithmable/version.rb
|
@@ -1,102 +0,0 @@
|
|
1
|
-
module Algorithmable
|
2
|
-
module DataStructs
|
3
|
-
module LinkedList
|
4
|
-
class Impl
|
5
|
-
include Enumerable
|
6
|
-
attr_reader :length
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@head = nil
|
10
|
-
@tail = nil
|
11
|
-
@length = 0
|
12
|
-
@op_counter = 0
|
13
|
-
end
|
14
|
-
|
15
|
-
def unshift(data)
|
16
|
-
link_head_node data
|
17
|
-
end
|
18
|
-
|
19
|
-
def push(data)
|
20
|
-
link_tail_node data
|
21
|
-
end
|
22
|
-
|
23
|
-
def first
|
24
|
-
@head ? @head.dup : fail_index_error
|
25
|
-
end
|
26
|
-
|
27
|
-
def last
|
28
|
-
@tail ? @tail.dup : fail_index_error
|
29
|
-
end
|
30
|
-
|
31
|
-
def each(&block)
|
32
|
-
next_node = @head
|
33
|
-
nodes = []
|
34
|
-
while next_node
|
35
|
-
nodes << next_node
|
36
|
-
next_node = next_node.succ
|
37
|
-
end
|
38
|
-
nodes.each(&block)
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def link_head_node(data)
|
44
|
-
prev_head = @head
|
45
|
-
node = make_node data, nil, prev_head
|
46
|
-
@head = node
|
47
|
-
|
48
|
-
if prev_head
|
49
|
-
prev_head.pred = node
|
50
|
-
else
|
51
|
-
@tail = node
|
52
|
-
end
|
53
|
-
|
54
|
-
bump_length!
|
55
|
-
bump_op_counter!
|
56
|
-
end
|
57
|
-
|
58
|
-
def link_tail_node(data)
|
59
|
-
prev_tail = @tail
|
60
|
-
node = make_node data, prev_tail, nil
|
61
|
-
@tail = node
|
62
|
-
|
63
|
-
if prev_tail
|
64
|
-
prev_tail.succ = node
|
65
|
-
else
|
66
|
-
@head = node
|
67
|
-
end
|
68
|
-
|
69
|
-
bump_length!
|
70
|
-
bump_op_counter!
|
71
|
-
end
|
72
|
-
|
73
|
-
def make_node(data, pred = nil, succ = nil)
|
74
|
-
Node.new data, pred, succ
|
75
|
-
end
|
76
|
-
|
77
|
-
def bump_length!
|
78
|
-
@length = @length.next
|
79
|
-
end
|
80
|
-
|
81
|
-
def bump_op_counter!
|
82
|
-
@op_counter = @op_counter.next
|
83
|
-
end
|
84
|
-
|
85
|
-
def fail_index_error(message = nil)
|
86
|
-
fail IndexError, message
|
87
|
-
end
|
88
|
-
|
89
|
-
class Node
|
90
|
-
attr_accessor :pred, :succ
|
91
|
-
attr_reader :data
|
92
|
-
|
93
|
-
def initialize(data, pred = nil, succ = nil)
|
94
|
-
@data = data
|
95
|
-
@pred = pred
|
96
|
-
@succ = succ
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|