skn_utils 3.3.2 → 3.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -2
- data/bin/benchmark.rb +81 -6
- data/lib/skn_utils/lists/circular_linked_list.rb +28 -29
- data/lib/skn_utils/lists/doubly_linked_list.rb +27 -28
- data/lib/skn_utils/lists/link_node.rb +3 -2
- data/lib/skn_utils/lists/linked_list.rb +23 -20
- data/lib/skn_utils/version.rb +1 -1
- data/spec/lib/skn_utils/lists/Circular_linked_list_spec.rb +1 -1
- data/spec/lib/skn_utils/lists/doubly_linked_list_spec.rb +1 -1
- data/spec/lib/skn_utils/lists/linked_list_spec.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32848790967a49e9c69c81c3cf46744ccc1fde9c
|
4
|
+
data.tar.gz: 5801f319e98845bc7454af452a6df47339e2eb58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25c689c0230fc7b07e24b3f2d13a490ee42fa67da69b3a61f0fc4546959abde80241f40004ac0c1548c73a92afdb2fbcb32d5da4f315b3856525d42ea6671d86
|
7
|
+
data.tar.gz: 9d9cd56d940ecf86e0da143286689fc8b3dcaa6161c179f9b60a815dd0ccd26d8508b466c6b68a3cfd7a432f41bd374ab4b86a774fb1d91ca6f145282e866fee
|
data/README.md
CHANGED
@@ -89,6 +89,9 @@ Ruby Gem containing a Ruby PORO (Plain Old Ruby Object) that can be instantiated
|
|
89
89
|
#clear -- removes all elements and return number of elements removed
|
90
90
|
#empty? -- returns true if list has no elements, otherwise false
|
91
91
|
#size -- returns total count of elements in the list
|
92
|
+
#sort!(:direction, &block) -- Sort existing list in place using :direction (:asc,:desc, :default) symbol
|
93
|
+
if block is given, overrides :direction and uses custom proc to compare values
|
94
|
+
block format is: {|a,b| a >= b }; example: 'll.sort(:default) {|a,b| a <= b}'
|
92
95
|
|
93
96
|
Modification: returns number of elements in the list after the operation
|
94
97
|
#insert(value) -- inserts value after node at current positon, or appends
|
@@ -98,8 +101,10 @@ Ruby Gem containing a Ruby PORO (Plain Old Ruby Object) that can be instantiated
|
|
98
101
|
#insert_after(position_value, value) -- finds node matching position_value, then appends new node
|
99
102
|
#remove(value) -- finds first node matching value, then destroys it
|
100
103
|
|
101
|
-
Initialization
|
102
|
-
#new(*
|
104
|
+
Initialization: optional &block to identify data key
|
105
|
+
#new(*vargs, &block) -- Instansiates new list and optionally creates nodes from each comma-seperated value;
|
106
|
+
also, assigns &block as default value identifier for find and sort operations
|
107
|
+
compare_key_block example: LinkedList.new({:key=>"Z"},{:key=>"S"},{:key=>"N"}) {|a| a[:key]}
|
103
108
|
|
104
109
|
|
105
110
|
## Public Methods: SknSettings ONLY
|
data/bin/benchmark.rb
CHANGED
@@ -1,11 +1,42 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
#
|
4
|
+
# Ref: https://github.com/evanphx/benchmark-ips
|
5
|
+
#
|
6
|
+
|
3
7
|
require 'bundler/setup'
|
4
8
|
require 'skn_utils'
|
5
9
|
require 'ostruct'
|
6
10
|
require 'benchmark/ips'
|
7
11
|
|
12
|
+
class GCSuite
|
13
|
+
def warming(*)
|
14
|
+
run_gc
|
15
|
+
end
|
16
|
+
|
17
|
+
def running(*)
|
18
|
+
run_gc
|
19
|
+
end
|
20
|
+
|
21
|
+
def warmup_stats(*)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_report(*)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def run_gc
|
30
|
+
GC.enable
|
31
|
+
GC.start
|
32
|
+
GC.disable
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
suite = GCSuite.new
|
37
|
+
|
8
38
|
Benchmark.ips do |x|
|
39
|
+
x.config(:suite => suite)
|
9
40
|
|
10
41
|
class RegularClass
|
11
42
|
attr_accessor :foo
|
@@ -31,13 +62,57 @@ Benchmark.ips do |x|
|
|
31
62
|
n.foo = :bar
|
32
63
|
n.foo
|
33
64
|
end
|
65
|
+
|
66
|
+
x.compare!
|
34
67
|
end
|
35
68
|
|
36
69
|
# Warming up --------------------------------------
|
37
|
-
# regular class
|
38
|
-
# OpenStruct class
|
39
|
-
# NestedResult class
|
70
|
+
# regular class 179.755k i/100ms
|
71
|
+
# OpenStruct class 11.367k i/100ms
|
72
|
+
# NestedResult class 9.674k i/100ms
|
73
|
+
# Calculating -------------------------------------
|
74
|
+
# regular class 3.674M (±17.4%) i/s - 17.256M in 5.001576s
|
75
|
+
# OpenStruct class 155.394k (±31.2%) i/s - 670.653k in 5.095404s
|
76
|
+
# NestedResult class 119.896k (±39.0%) i/s - 493.374k in 5.212147s
|
77
|
+
#
|
78
|
+
# Comparison:
|
79
|
+
# regular class: 3673640.5 i/s
|
80
|
+
# OpenStruct class: 155394.0 i/s - 23.64x slower
|
81
|
+
# NestedResult class: 119896.1 i/s - 30.64x slower
|
82
|
+
#
|
83
|
+
# Warming up --------------------------------------
|
84
|
+
# LinkedList Ops 2.297k i/100ms
|
85
|
+
# Array Ops 34.468k i/100ms
|
40
86
|
# Calculating -------------------------------------
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
87
|
+
# LinkedList Ops 17.015k (±35.2%) i/s - 71.207k in 5.100193s
|
88
|
+
# Array Ops 377.943k (± 7.3%) i/s - 1.896M in 5.048217s
|
89
|
+
#
|
90
|
+
# Comparison:
|
91
|
+
# Array Ops: 377942.7 i/s
|
92
|
+
# LinkedList Ops: 17015.4 i/s - 22.21x slower
|
93
|
+
|
94
|
+
|
95
|
+
Benchmark.ips do |x|
|
96
|
+
x.config(:suite => suite)
|
97
|
+
|
98
|
+
adders = [50, 10, 110, 6, 30, 101, 12, 33, 4]
|
99
|
+
vargs = [70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
|
100
|
+
|
101
|
+
x.report('LinkedList Ops') do
|
102
|
+
ll = SknUtils::Lists::LinkedList.new(*vargs)
|
103
|
+
adders.each {|x| ll.insert_after(74, x)}
|
104
|
+
value = ll.sort!
|
105
|
+
ll.first
|
106
|
+
ll.clear
|
107
|
+
end
|
108
|
+
|
109
|
+
x.report('Array Ops') do
|
110
|
+
ary = Array.new(vargs)
|
111
|
+
adders.each {|x| ary.insert(5, x)}
|
112
|
+
value = ary.sort!
|
113
|
+
ary.first
|
114
|
+
ary.clear
|
115
|
+
end
|
116
|
+
|
117
|
+
x.compare!
|
118
|
+
end
|
@@ -7,15 +7,16 @@ module SknUtils
|
|
7
7
|
class CircularLinkedList
|
8
8
|
attr_accessor :size
|
9
9
|
|
10
|
-
def initialize(*vargs, &
|
10
|
+
def initialize(*vargs, &compare_key_proc)
|
11
11
|
@current = nil
|
12
12
|
@head = nil
|
13
13
|
@tail = nil
|
14
14
|
@size = 0
|
15
15
|
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
16
|
+
@match_value = block_given? ? compare_key_proc : lambda {|obj| obj }
|
17
|
+
@sort_ascending = lambda {|a_obj,b_obj| @match_value.call(a_obj) >= @match_value.call(b_obj)}
|
18
|
+
@sort_descending = lambda {|a_obj,b_obj| @match_value.call(a_obj) <= @match_value.call(b_obj)}
|
19
|
+
@sort_condition = @sort_ascending
|
19
20
|
|
20
21
|
vargs.each {|value| insert(value) }
|
21
22
|
first if vargs.size > 1
|
@@ -107,7 +108,7 @@ module SknUtils
|
|
107
108
|
# return new size
|
108
109
|
def insert_before(position_value, value)
|
109
110
|
target = find_by_value(position_value)
|
110
|
-
node = LinkNode.new(value, target, :circle_before)
|
111
|
+
node = LinkNode.new(value, target, :circle_before, &@match_value)
|
111
112
|
@current = node if target
|
112
113
|
self.head = node if head === target
|
113
114
|
self.tail = node if tail.nil?
|
@@ -117,7 +118,7 @@ module SknUtils
|
|
117
118
|
# return new size
|
118
119
|
def insert_after(position_value, value)
|
119
120
|
target = find_by_value(position_value)
|
120
|
-
node = LinkNode.new(value, target, :circle_after)
|
121
|
+
node = LinkNode.new(value, target, :circle_after, &@match_value)
|
121
122
|
@current = node
|
122
123
|
self.head = node if head.nil?
|
123
124
|
self.tail = node if tail === target
|
@@ -166,12 +167,12 @@ module SknUtils
|
|
166
167
|
position = head
|
167
168
|
if block_given?
|
168
169
|
while position do
|
169
|
-
|
170
|
+
block.call( position.value.dup )
|
170
171
|
position = position.next
|
171
172
|
break if position === @current
|
172
173
|
end
|
173
174
|
else
|
174
|
-
Enumerator.new do |yielder
|
175
|
+
Enumerator.new do |yielder|
|
175
176
|
while position do
|
176
177
|
yielder << position.value.dup
|
177
178
|
position = position.next
|
@@ -195,19 +196,17 @@ module SknUtils
|
|
195
196
|
end
|
196
197
|
|
197
198
|
# block format: sort condition : {|a_obj,b_obj| a_obj >= b_obj}
|
198
|
-
def sort!(direction_sym=:default, &
|
199
|
-
active_sort_condition = block_given? ?
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
)
|
210
|
-
sorted = merge_sort(to_a, active_sort_condition)
|
199
|
+
def sort!(direction_sym=:default, &compare_sort_proc)
|
200
|
+
@active_sort_condition = block_given? ? compare_sort_proc :
|
201
|
+
case direction_sym
|
202
|
+
when :asc
|
203
|
+
@sort_ascending
|
204
|
+
when :desc
|
205
|
+
@sort_descending
|
206
|
+
else
|
207
|
+
@sort_condition
|
208
|
+
end
|
209
|
+
sorted = merge_sort(to_a)
|
211
210
|
clear
|
212
211
|
sorted.each {|item| insert(item) }
|
213
212
|
size
|
@@ -218,10 +217,10 @@ module SknUtils
|
|
218
217
|
attr_accessor :head, :tail
|
219
218
|
|
220
219
|
def find_by_value(value)
|
221
|
-
return nil if head.nil?
|
220
|
+
return nil if head.nil? or value.nil? or size == 0
|
222
221
|
prior = head
|
223
222
|
target = prior
|
224
|
-
while not target.match_by_value(value)
|
223
|
+
while target and not target.match_by_value(value)
|
225
224
|
prior = target
|
226
225
|
target = prior.next
|
227
226
|
@current = target if target
|
@@ -239,23 +238,23 @@ module SknUtils
|
|
239
238
|
|
240
239
|
# Merged Sort via Ref: http://rubyalgorithms.com/merge_sort.html
|
241
240
|
# arr is Array to be sorted, sort_cond is Proc expecting a/b params returning true/false
|
242
|
-
def merge_sort(arr
|
241
|
+
def merge_sort(arr)
|
243
242
|
return arr if arr.size < 2
|
244
243
|
|
245
244
|
middle = arr.size / 2
|
246
245
|
|
247
|
-
left = merge_sort(arr[0...middle]
|
248
|
-
right = merge_sort(arr[middle..arr.size]
|
246
|
+
left = merge_sort(arr[0...middle])
|
247
|
+
right = merge_sort(arr[middle..arr.size])
|
249
248
|
|
250
|
-
merge(left, right
|
249
|
+
merge(left, right)
|
251
250
|
end
|
252
251
|
|
253
|
-
def merge(left, right
|
252
|
+
def merge(left, right)
|
254
253
|
sorted = []
|
255
254
|
|
256
255
|
while left.any? && right.any?
|
257
256
|
|
258
|
-
if
|
257
|
+
if @active_sort_condition.call(left.first, right.first)
|
259
258
|
sorted.push right.shift
|
260
259
|
else
|
261
260
|
sorted.push left.shift
|
@@ -8,15 +8,16 @@ module SknUtils
|
|
8
8
|
class DoublyLinkedList
|
9
9
|
attr_accessor :size
|
10
10
|
|
11
|
-
def initialize(*vargs, &
|
11
|
+
def initialize(*vargs, &compare_key_proc)
|
12
12
|
@current = nil
|
13
13
|
@head = nil
|
14
14
|
@tail = nil
|
15
15
|
@size = 0
|
16
16
|
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
17
|
+
@match_value = block_given? ? compare_key_proc : lambda {|obj| obj }
|
18
|
+
@sort_ascending = lambda {|a_obj,b_obj| @match_value.call(a_obj) >= @match_value.call(b_obj)}
|
19
|
+
@sort_descending = lambda {|a_obj,b_obj| @match_value.call(a_obj) <= @match_value.call(b_obj)}
|
20
|
+
@sort_condition = @sort_ascending
|
20
21
|
|
21
22
|
vargs.each {|value| insert(value) }
|
22
23
|
first if vargs.size > 1
|
@@ -105,7 +106,7 @@ module SknUtils
|
|
105
106
|
# return new size
|
106
107
|
def insert_before(position_value, value)
|
107
108
|
target = find_by_value(position_value)
|
108
|
-
node = LinkNode.new(value, target, :before)
|
109
|
+
node = LinkNode.new(value, target, :before, &@match_value)
|
109
110
|
@current = node if target
|
110
111
|
self.head = node if head === target
|
111
112
|
self.tail = node if tail.nil?
|
@@ -115,7 +116,7 @@ module SknUtils
|
|
115
116
|
# return new size
|
116
117
|
def insert_after(position_value, value)
|
117
118
|
target = find_by_value(position_value)
|
118
|
-
node = LinkNode.new(value, target, :after)
|
119
|
+
node = LinkNode.new(value, target, :after, &@match_value)
|
119
120
|
@current = node
|
120
121
|
self.head = node if head.nil?
|
121
122
|
self.tail = node if tail === target
|
@@ -164,7 +165,7 @@ module SknUtils
|
|
164
165
|
position = head
|
165
166
|
if block_given?
|
166
167
|
while position do
|
167
|
-
|
168
|
+
block.call( position.value.dup )
|
168
169
|
position = position.next
|
169
170
|
break if position === @current
|
170
171
|
end
|
@@ -193,19 +194,17 @@ module SknUtils
|
|
193
194
|
end
|
194
195
|
|
195
196
|
# block format: sort condition : {|a_obj,b_obj| a_obj >= b_obj}
|
196
|
-
def sort!(direction_sym=:default, &
|
197
|
-
active_sort_condition = block_given? ?
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
)
|
208
|
-
sorted = merge_sort(to_a, active_sort_condition)
|
197
|
+
def sort!(direction_sym=:default, &compare_sort_proc)
|
198
|
+
@active_sort_condition = block_given? ? compare_sort_proc :
|
199
|
+
case direction_sym
|
200
|
+
when :asc
|
201
|
+
@sort_ascending
|
202
|
+
when :desc
|
203
|
+
@sort_descending
|
204
|
+
else
|
205
|
+
@sort_condition
|
206
|
+
end
|
207
|
+
sorted = merge_sort(to_a)
|
209
208
|
clear
|
210
209
|
sorted.each {|item| insert(item) }
|
211
210
|
size
|
@@ -216,10 +215,10 @@ module SknUtils
|
|
216
215
|
attr_accessor :head, :tail
|
217
216
|
|
218
217
|
def find_by_value(value)
|
219
|
-
return nil if head.nil?
|
218
|
+
return nil if head.nil? or value.nil?
|
220
219
|
prior = head
|
221
220
|
target = prior
|
222
|
-
while not target.match_by_value(value)
|
221
|
+
while target and not target.match_by_value(value)
|
223
222
|
prior = target
|
224
223
|
target = prior.next
|
225
224
|
@current = target if target
|
@@ -237,23 +236,23 @@ module SknUtils
|
|
237
236
|
|
238
237
|
# Merged Sort via Ref: http://rubyalgorithms.com/merge_sort.html
|
239
238
|
# arr is Array to be sorted, sort_cond is Proc expecting a/b params returning true/false
|
240
|
-
def merge_sort(arr
|
239
|
+
def merge_sort(arr)
|
241
240
|
return arr if arr.size < 2
|
242
241
|
|
243
242
|
middle = arr.size / 2
|
244
243
|
|
245
|
-
left = merge_sort(arr[0...middle]
|
246
|
-
right = merge_sort(arr[middle..arr.size]
|
244
|
+
left = merge_sort(arr[0...middle])
|
245
|
+
right = merge_sort(arr[middle..arr.size])
|
247
246
|
|
248
|
-
merge(left, right
|
247
|
+
merge(left, right)
|
249
248
|
end
|
250
249
|
|
251
|
-
def merge(left, right
|
250
|
+
def merge(left, right)
|
252
251
|
sorted = []
|
253
252
|
|
254
253
|
while left.any? && right.any?
|
255
254
|
|
256
|
-
if
|
255
|
+
if @active_sort_condition.call(left.first, right.first)
|
257
256
|
sorted.push right.shift
|
258
257
|
else
|
259
258
|
sorted.push left.shift
|
@@ -8,10 +8,11 @@ module SknUtils
|
|
8
8
|
class LinkNode
|
9
9
|
attr_accessor :prev, :next, :value
|
10
10
|
|
11
|
-
def initialize(val, anchor_node=nil, strategy=:after)
|
11
|
+
def initialize(val, anchor_node=nil, strategy=:after, &cmp_key)
|
12
12
|
@value = val
|
13
13
|
@prev = nil
|
14
14
|
@next = nil
|
15
|
+
@cmp_proc = block_given? ? cmp_key : lambda {|a| a }
|
15
16
|
|
16
17
|
case strategy
|
17
18
|
when :single # after logic
|
@@ -39,7 +40,7 @@ module SknUtils
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def match_by_value(other_value)
|
42
|
-
|
43
|
+
@cmp_proc.call(value) === @cmp_proc.call(other_value)
|
43
44
|
end
|
44
45
|
|
45
46
|
# returns next node
|
@@ -8,16 +8,19 @@ module SknUtils
|
|
8
8
|
class LinkedList
|
9
9
|
attr_accessor :size
|
10
10
|
|
11
|
-
|
11
|
+
# &compare_key_proc supplies an method to identify
|
12
|
+
# the key of an object for comparison purposes
|
13
|
+
def initialize(*vargs, &compare_key_proc)
|
12
14
|
@sort_condition = nil
|
13
15
|
@current = nil
|
14
16
|
@head = nil
|
15
17
|
@tail = nil
|
16
18
|
@size = 0
|
17
19
|
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
20
|
+
@match_value = block_given? ? compare_key_proc : lambda {|obj| obj }
|
21
|
+
@sort_ascending = lambda {|a_obj,b_obj| @match_value.call(a_obj) >= @match_value.call(b_obj)}
|
22
|
+
@sort_descending = lambda {|a_obj,b_obj| @match_value.call(a_obj) <= @match_value.call(b_obj)}
|
23
|
+
@sort_condition = @sort_ascending
|
21
24
|
|
22
25
|
vargs.each {|value| insert(value) }
|
23
26
|
first if vargs.size > 1
|
@@ -96,7 +99,7 @@ module SknUtils
|
|
96
99
|
# return new size
|
97
100
|
def insert_before(position_value, value)
|
98
101
|
prior, target = find_by_value(position_value)
|
99
|
-
node = LinkNode.new(value, prior, :single)
|
102
|
+
node = LinkNode.new(value, prior, :single, &@match_value)
|
100
103
|
node.next = target if target
|
101
104
|
self.head = node if head === target
|
102
105
|
self.tail = node if tail.nil?
|
@@ -107,7 +110,7 @@ module SknUtils
|
|
107
110
|
# return new size
|
108
111
|
def insert_after(position_value, value)
|
109
112
|
prior, target = find_by_value(position_value)
|
110
|
-
node = LinkNode.new(value, target, :single)
|
113
|
+
node = LinkNode.new(value, target, :single, &@match_value)
|
111
114
|
self.head = node if head.nil?
|
112
115
|
self.tail = node if tail === target
|
113
116
|
@current = node
|
@@ -118,8 +121,8 @@ module SknUtils
|
|
118
121
|
def remove(value)
|
119
122
|
@current, target_node = find_by_value(value)
|
120
123
|
@current.next = target_node.remove!
|
121
|
-
tail = @current.next if tail === target_node
|
122
|
-
head = @current if head === target_node
|
124
|
+
self.tail = @current.next if tail === target_node
|
125
|
+
self.head = @current if head === target_node
|
123
126
|
self.size -= 1
|
124
127
|
end
|
125
128
|
|
@@ -151,7 +154,7 @@ module SknUtils
|
|
151
154
|
position = head
|
152
155
|
if block_given?
|
153
156
|
while position do
|
154
|
-
|
157
|
+
block.call(position.value.dup )
|
155
158
|
position = position.next
|
156
159
|
end
|
157
160
|
else
|
@@ -178,8 +181,8 @@ module SknUtils
|
|
178
181
|
end
|
179
182
|
|
180
183
|
# block format: sort condition : {|a_obj,b_obj| a_obj >= b_obj}
|
181
|
-
def sort!(direction_sym=:default, &
|
182
|
-
active_sort_condition = block_given? ?
|
184
|
+
def sort!(direction_sym=:default, &compare_sort_proc)
|
185
|
+
@active_sort_condition = block_given? ? compare_sort_proc :
|
183
186
|
case direction_sym
|
184
187
|
when :asc
|
185
188
|
@sort_ascending
|
@@ -189,7 +192,7 @@ module SknUtils
|
|
189
192
|
@sort_condition
|
190
193
|
end
|
191
194
|
|
192
|
-
sorted = merge_sort(to_a
|
195
|
+
sorted = merge_sort(to_a)
|
193
196
|
clear
|
194
197
|
sorted.each {|item| insert(item) }
|
195
198
|
size
|
@@ -200,10 +203,10 @@ module SknUtils
|
|
200
203
|
attr_accessor :head, :tail
|
201
204
|
|
202
205
|
def find_by_value(value)
|
203
|
-
return [nil,nil] if head.nil?
|
206
|
+
return [nil,nil] if head.nil? or value.nil?
|
204
207
|
prior = head
|
205
208
|
target = prior
|
206
|
-
while not target.match_by_value(value)
|
209
|
+
while target and not target.match_by_value(value)
|
207
210
|
prior = target
|
208
211
|
target = prior.next
|
209
212
|
@current = target if target
|
@@ -221,23 +224,23 @@ module SknUtils
|
|
221
224
|
|
222
225
|
# Merged Sort via Ref: http://rubyalgorithms.com/merge_sort.html
|
223
226
|
# arr is Array to be sorted, sort_cond is Proc expecting a/b params returning true/false
|
224
|
-
def merge_sort(arr
|
227
|
+
def merge_sort(arr)
|
225
228
|
return arr if arr.size < 2
|
226
229
|
|
227
230
|
middle = arr.size / 2
|
228
231
|
|
229
|
-
left = merge_sort(arr[0...middle]
|
230
|
-
right = merge_sort(arr[middle..arr.size]
|
232
|
+
left = merge_sort(arr[0...middle])
|
233
|
+
right = merge_sort(arr[middle..arr.size])
|
231
234
|
|
232
|
-
merge(left, right
|
235
|
+
merge(left, right)
|
233
236
|
end
|
234
237
|
|
235
|
-
def merge(left, right
|
238
|
+
def merge(left, right)
|
236
239
|
sorted = []
|
237
240
|
|
238
241
|
while left.any? && right.any?
|
239
242
|
|
240
|
-
if
|
243
|
+
if @active_sort_condition.call(left.first, right.first)
|
241
244
|
sorted.push right.shift
|
242
245
|
else
|
243
246
|
sorted.push left.shift
|
data/lib/skn_utils/version.rb
CHANGED
@@ -243,7 +243,7 @@ RSpec.describe SknUtils::Lists::CircularLinkedList, "Circular LinkedList " do
|
|
243
243
|
let(:alpha_list) { described_class.new('Z', 'K', 'S', 'n', 's', 'z', 'k', 'N', 'o', 'A') }
|
244
244
|
let(:hash_list) { described_class.new({key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'},
|
245
245
|
{key: 'z'}, {key: 'k'}, {key: 'N'}, {key: 'o'}, {key: 'A'}
|
246
|
-
|
246
|
+
) {|a| a[:key]}
|
247
247
|
}
|
248
248
|
|
249
249
|
it "#sort! redefines numeric list in asending order" do
|
@@ -243,7 +243,7 @@ RSpec.describe SknUtils::Lists::DoublyLinkedList, "Double-Ended LinkedList " do
|
|
243
243
|
let(:alpha_list) { described_class.new('Z', 'K', 'S', 'n', 's', 'z', 'k', 'N', 'o', 'A') }
|
244
244
|
let(:hash_list) { described_class.new({key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'},
|
245
245
|
{key: 'z'}, {key: 'k'}, {key: 'N'}, {key: 'o'}, {key: 'A'}
|
246
|
-
|
246
|
+
) {|a| a[:key]}
|
247
247
|
}
|
248
248
|
|
249
249
|
it "#sort! redefines numeric list in asending order" do
|
@@ -236,7 +236,7 @@ RSpec.describe SknUtils::Lists::LinkedList, "Singular LinkedList " do
|
|
236
236
|
let(:alpha_list) { described_class.new('Z', 'K', 'S', 'n', 's', 'z', 'k', 'N', 'o', 'A') }
|
237
237
|
let(:hash_list) { described_class.new({key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'},
|
238
238
|
{key: 'z'}, {key: 'k'}, {key: 'N'}, {key: 'o'}, {key: 'A'}
|
239
|
-
|
239
|
+
) {|a| a[:key]}
|
240
240
|
}
|
241
241
|
|
242
242
|
it "#sort! redefines numeric list in asending order" do
|