xenum 0.1.3 → 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 +5 -1
- data/lib/xenum/merge_sort.rb +121 -0
- data/lib/xenum/version.rb +1 -1
- data/lib/xenum.rb +7 -60
- 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)
|
@@ -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|
|
@@ -56,69 +60,12 @@ module Enumerable
|
|
56
60
|
end
|
57
61
|
|
58
62
|
def merge_sort(*enums)
|
59
|
-
|
60
|
-
|
61
|
-
self
|
62
|
-
when 1
|
63
|
-
_merge_sort(enums[0])
|
64
|
-
else
|
65
|
-
enums2 = enums.pop((enums.size / 2) - 1)
|
66
|
-
enum2 = enums.pop
|
67
|
-
e2 = enum2.merge_sort(*enums2)
|
68
|
-
e1 = merge_sort(*enums)
|
69
|
-
e1.merge_sort(e2)
|
70
|
-
end
|
63
|
+
enums << self
|
64
|
+
Xenum::MergeSort.iter(*enums)
|
71
65
|
end
|
72
66
|
|
73
67
|
private
|
74
68
|
|
75
|
-
def _merge_sort(that)
|
76
|
-
this = Enumerator === self ? self : self.to_enum
|
77
|
-
that = Enumerator === that ? that : that.to_enum
|
78
|
-
|
79
|
-
Enumerator.new do |e|
|
80
|
-
a = Xenum::NULL
|
81
|
-
b = Xenum::NULL
|
82
|
-
remain = nil
|
83
|
-
|
84
|
-
loop do
|
85
|
-
if a == Xenum::NULL
|
86
|
-
a = begin
|
87
|
-
this.next
|
88
|
-
rescue StopIteration
|
89
|
-
remain = that
|
90
|
-
break
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
if b == Xenum::NULL
|
95
|
-
b = begin
|
96
|
-
that.next
|
97
|
-
rescue StopIteration
|
98
|
-
remain = this
|
99
|
-
break
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
if (a <=> b) <= 0
|
104
|
-
e.yield(a)
|
105
|
-
a = Xenum::NULL
|
106
|
-
else
|
107
|
-
e.yield(b)
|
108
|
-
b = Xenum::NULL
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
e.yield(a) if a != Xenum::NULL
|
113
|
-
e.yield(b) if b != Xenum::NULL
|
114
|
-
|
115
|
-
loop do
|
116
|
-
e.yield(remain.next)
|
117
|
-
rescue StopIteration
|
118
|
-
break
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
69
|
|
123
70
|
def lazy_insert_neg(index, objs)
|
124
71
|
these = Enumerator === self ? self : self.to_enum
|
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
|