xenum 0.1.2 → 0.1.4
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +9 -1
- data/lib/xenum/merge_sort.rb +121 -0
- data/lib/xenum/version.rb +1 -1
- data/lib/xenum.rb +9 -47
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b26e4083a610a02bfcaf4fcd7b74902c65d1468950ad62e09e0f69be08fa33e2
|
4
|
+
data.tar.gz: 3fafdc0f08284afe73ecd91701e48840ea103fa68e3694c682d3633d03fc7176
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1731083f8b65c5e86be5713e65476a2aa8aec75b42321f9041ee80c02e94d2b5b72e536094be03ca24a526ea1023093a08e13108f73de4439ab12fc4e9947f4
|
7
|
+
data.tar.gz: 925ffb7471110f7743abd3ffed92010c3fad9db65ea2952a283c590c9cf37db28fb19c583646f8cf268990398839c68df3fc75c3c6e02ff96f543ad88d7921d5
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -42,6 +42,10 @@ works like `Array#insert`, but not limited to `Array`
|
|
42
42
|
# [0, 1, 2, 3, 4, 5, 6, 7, "a", "b", 8, 9]
|
43
43
|
```
|
44
44
|
|
45
|
+
### lazy_unshift
|
46
|
+
|
47
|
+
just like `lazy_insert(0, ...)`
|
48
|
+
|
45
49
|
### lazy_product
|
46
50
|
|
47
51
|
works like `Array#product`, but not limited to `Array`
|
@@ -56,7 +60,7 @@ works like `Array#product`, but not limited to `Array`
|
|
56
60
|
|
57
61
|
### merge_sort
|
58
62
|
|
59
|
-
lazily merge sort
|
63
|
+
lazily merge sort `Enumerable`
|
60
64
|
|
61
65
|
```ruby
|
62
66
|
e = (6..8).merge_sort([3,4,5]).merge_sort(3.times)
|
@@ -67,4 +71,8 @@ e.take(5)
|
|
67
71
|
|
68
72
|
[(6..8), [3,4,5], 3.times].reduce(&:merge_sort).to_a
|
69
73
|
# [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
74
|
+
|
75
|
+
# same result but faster
|
76
|
+
(6..8).merge_sort([3,4,5], 3.times).to_a
|
77
|
+
# [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
70
78
|
```
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Xenum
|
2
|
+
module MergeSort
|
3
|
+
NULL = Object.new
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def recur(*enums)
|
7
|
+
case enums.size
|
8
|
+
when 0
|
9
|
+
[].to_enum
|
10
|
+
when 1
|
11
|
+
enums[0]
|
12
|
+
else
|
13
|
+
enums2 = recur(*enums.pop(enums.size / 2))
|
14
|
+
enums1 = recur(*enums)
|
15
|
+
_recur(enums1, enums2)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def iter(*enums)
|
20
|
+
Enumerator.new do |yielder|
|
21
|
+
enums = enums.each_with_object([]) do |e, arr|
|
22
|
+
c = Candidate.new(e)
|
23
|
+
arr << c if c.value != NULL
|
24
|
+
end
|
25
|
+
enums.sort!{ |a, b| b <=> a }
|
26
|
+
|
27
|
+
resort = -> do
|
28
|
+
i = -1
|
29
|
+
x = enums[i]
|
30
|
+
loop do
|
31
|
+
e = enums[i-1]
|
32
|
+
break unless e
|
33
|
+
break if (e <=> x) >= 0
|
34
|
+
enums[i] = e
|
35
|
+
i -= 1
|
36
|
+
end
|
37
|
+
enums[i] = x
|
38
|
+
end
|
39
|
+
|
40
|
+
loop do
|
41
|
+
break if enums.empty?
|
42
|
+
resort.call
|
43
|
+
least = enums[-1]
|
44
|
+
yielder << least.value
|
45
|
+
least.fetch
|
46
|
+
next enums.pop if least.value == NULL
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def _recur(this, that)
|
54
|
+
this = this.to_enum unless Enumerator === this
|
55
|
+
that = that.to_enum unless Enumerator === that
|
56
|
+
|
57
|
+
Enumerator.new do |e|
|
58
|
+
a = NULL
|
59
|
+
b = NULL
|
60
|
+
remain = nil
|
61
|
+
|
62
|
+
loop do
|
63
|
+
if a == NULL
|
64
|
+
a = begin
|
65
|
+
this.next
|
66
|
+
rescue StopIteration
|
67
|
+
remain = that
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if b == NULL
|
73
|
+
b = begin
|
74
|
+
that.next
|
75
|
+
rescue StopIteration
|
76
|
+
remain = this
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if (a <=> b) <= 0
|
82
|
+
e.yield(a)
|
83
|
+
a = NULL
|
84
|
+
else
|
85
|
+
e.yield(b)
|
86
|
+
b = NULL
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
e.yield(a) if a != NULL
|
91
|
+
e.yield(b) if b != NULL
|
92
|
+
|
93
|
+
loop do
|
94
|
+
e.yield(remain.next)
|
95
|
+
rescue StopIteration
|
96
|
+
break
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Candidate
|
103
|
+
attr_accessor :value
|
104
|
+
|
105
|
+
def initialize(enum)
|
106
|
+
@enum = Enumerator === enum ? enum : enum.to_enum
|
107
|
+
fetch
|
108
|
+
end
|
109
|
+
|
110
|
+
def <=>(another)
|
111
|
+
value <=> another.value
|
112
|
+
end
|
113
|
+
|
114
|
+
def fetch
|
115
|
+
@value = @enum.next
|
116
|
+
rescue StopIteration
|
117
|
+
@value = NULL
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/xenum/version.rb
CHANGED
data/lib/xenum.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "xenum/version"
|
4
|
+
require_relative "xenum/merge_sort"
|
4
5
|
|
5
6
|
module Xenum
|
6
|
-
NULL = Object.new
|
7
7
|
end
|
8
8
|
|
9
9
|
module Enumerable
|
@@ -36,6 +36,10 @@ module Enumerable
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def lazy_unshift(*objs)
|
40
|
+
lazy_insert(0, *objs)
|
41
|
+
end
|
42
|
+
|
39
43
|
def lazy_product(*enums)
|
40
44
|
if enums.empty?
|
41
45
|
return Enumerator.new do |yielder|
|
@@ -55,56 +59,14 @@ module Enumerable
|
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
58
|
-
def merge_sort(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Enumerator.new do |e|
|
63
|
-
a = Xenum::NULL
|
64
|
-
b = Xenum::NULL
|
65
|
-
remain = nil
|
66
|
-
|
67
|
-
loop do
|
68
|
-
if a == Xenum::NULL
|
69
|
-
a = begin
|
70
|
-
this.next
|
71
|
-
rescue StopIteration
|
72
|
-
remain = that
|
73
|
-
break
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
if b == Xenum::NULL
|
78
|
-
b = begin
|
79
|
-
that.next
|
80
|
-
rescue StopIteration
|
81
|
-
remain = this
|
82
|
-
break
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
if (a <=> b) <= 0
|
87
|
-
e.yield(a)
|
88
|
-
a = Xenum::NULL
|
89
|
-
else
|
90
|
-
e.yield(b)
|
91
|
-
b = Xenum::NULL
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
e.yield(a) if a != Xenum::NULL
|
96
|
-
e.yield(b) if b != Xenum::NULL
|
97
|
-
|
98
|
-
loop do
|
99
|
-
e.yield(remain.next)
|
100
|
-
rescue StopIteration
|
101
|
-
break
|
102
|
-
end
|
103
|
-
end
|
62
|
+
def merge_sort(*enums)
|
63
|
+
enums << self
|
64
|
+
Xenum::MergeSort.iter(*enums)
|
104
65
|
end
|
105
66
|
|
106
67
|
private
|
107
68
|
|
69
|
+
|
108
70
|
def lazy_insert_neg(index, objs)
|
109
71
|
these = Enumerator === self ? self : self.to_enum
|
110
72
|
queue = []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xenum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ken
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -24,6 +24,7 @@ files:
|
|
24
24
|
- README.md
|
25
25
|
- Rakefile
|
26
26
|
- lib/xenum.rb
|
27
|
+
- lib/xenum/merge_sort.rb
|
27
28
|
- lib/xenum/version.rb
|
28
29
|
- sig/xenum.rbs
|
29
30
|
homepage: https://github.com/turnon/xenum
|