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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a22147054180684998dfbea79223da8a588abf7e0f923e3a1189b76a52d4335e
4
- data.tar.gz: bd0b21403fa4d114cbb5139f1c514226648f8de71406da76b6bfb086375346fb
3
+ metadata.gz: b26e4083a610a02bfcaf4fcd7b74902c65d1468950ad62e09e0f69be08fa33e2
4
+ data.tar.gz: 3fafdc0f08284afe73ecd91701e48840ea103fa68e3694c682d3633d03fc7176
5
5
  SHA512:
6
- metadata.gz: 94efb08dd1112f2bd67b3380b2e104d48392ff0467f39b28e9830b686de9778d5956a43db1f353b31b371e77585ea836a260b9951c89d5ba91d705ad0617f6e4
7
- data.tar.gz: fdbaafde2073b72fbb450dcab5a134d7002cdefab5a89428a3977caaee0aac7eaaf1ef5dd9e6cf4ae82417032ddcc723931579f7a271507ab326634e88fb7329
6
+ metadata.gz: b1731083f8b65c5e86be5713e65476a2aa8aec75b42321f9041ee80c02e94d2b5b72e536094be03ca24a526ea1023093a08e13108f73de4439ab12fc4e9947f4
7
+ data.tar.gz: 925ffb7471110f7743abd3ffed92010c3fad9db65ea2952a283c590c9cf37db28fb19c583646f8cf268990398839c68df3fc75c3c6e02ff96f543ad88d7921d5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- xenum (0.1.1)
4
+ xenum (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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 two sorted `Enumerable`
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Xenum
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
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(that)
59
- this = Enumerator === self ? self : self.to_enum
60
- that = Enumerator === that ? that : that.to_enum
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.2
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-18 00:00:00.000000000 Z
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