unodos 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +29 -0
- data/LICENSE.txt +21 -0
- data/README.md +29 -0
- data/Rakefile +10 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/unodos/base.rb +30 -0
- data/lib/unodos/formatter.rb +26 -0
- data/lib/unodos/infinite.rb +75 -0
- data/lib/unodos/solver.rb +169 -0
- data/lib/unodos/sugar.rb +27 -0
- data/lib/unodos/version.rb +3 -0
- data/lib/unodos.rb +8 -0
- data/unodos.gemspec +26 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c1d6382656d25e32af8472594431238876b8d272f5e1dd3f11a4280dba447ec1
|
4
|
+
data.tar.gz: 833359582ee40ccc6bcd9aa8c0ff4ad31ef4a5669e0221ffe374e38d2be21ba9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7c1940eb0e70201528757a3ef91eec0fbc573a70813bf8b0eb88f8e6837ef741840be93a29226fc02101771b6adbdc956cc900c4b9096d95c6f642b43796eca9
|
7
|
+
data.tar.gz: 5a79be567967b770e3441430960913e8cbd35718d246f2d31db349bdba5310b3c786905d3855013e49d4523c0aee835eb3c4b9d4d0dc1e2cf1e3e803bdff2ea2
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
coverage/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
unodos (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
docile (1.3.2)
|
10
|
+
json (2.3.0)
|
11
|
+
minitest (5.13.0)
|
12
|
+
rake (12.3.3)
|
13
|
+
simplecov (0.17.1)
|
14
|
+
docile (~> 1.1)
|
15
|
+
json (>= 1.8, < 3)
|
16
|
+
simplecov-html (~> 0.10.0)
|
17
|
+
simplecov-html (0.10.2)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
minitest (~> 5.0)
|
24
|
+
rake (~> 12.0)
|
25
|
+
simplecov
|
26
|
+
unodos!
|
27
|
+
|
28
|
+
BUNDLED WITH
|
29
|
+
2.1.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 tompng
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Unodos
|
2
|
+
|
3
|
+
```ruby
|
4
|
+
require 'unodos'
|
5
|
+
Unodos[1,2,3].take(5) # => [1,2,3,4,5]
|
6
|
+
Unodos[1,2,4].take(5) # => [1,2,4,8,16]
|
7
|
+
Unodos[1,1,2,3,5].take(8) # => [1,1,2,3,5,8,13,21]
|
8
|
+
Unodos[1,1,2,4,3,9,4,16,5].take(10) #=> [1,1,2,4,3,9,4,16,5,25]
|
9
|
+
|
10
|
+
# to see the generated rule
|
11
|
+
Unodos[4,1,0,1,4,9].rule #=> "a[n]=4-4*n+n**2"
|
12
|
+
Unodos[1,2,4,5,7,8].rule #=> "a[n]=-a[n-1]+3*n"
|
13
|
+
```
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'unodos'
|
19
|
+
```
|
20
|
+
|
21
|
+
## Syntax Sugar
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'unodos/sugar' # will add Array#infinite
|
25
|
+
[1,2,3].infinite.take(5) #=> [1,2,3,4,5]
|
26
|
+
using Unodos::Sugar # will change [numbers, number..].some_method
|
27
|
+
[1,2,3..].take(5) #=> [1,2,3,4,5]
|
28
|
+
[1,1,2,3,5..].find_index(144) #=> 11
|
29
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'unodos'
|
5
|
+
require 'unodos/sugar'
|
6
|
+
using Unodos::Sugar
|
7
|
+
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
10
|
+
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
12
|
+
# require "pry"
|
13
|
+
# Pry.start
|
14
|
+
|
15
|
+
require 'irb'
|
16
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/unodos/base.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Unodos
|
2
|
+
class NamedBase
|
3
|
+
attr_reader :name, :proc
|
4
|
+
|
5
|
+
def initialize(name, &block)
|
6
|
+
@name = name
|
7
|
+
@proc = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def differential_level
|
11
|
+
0
|
12
|
+
end
|
13
|
+
|
14
|
+
alias to_s name
|
15
|
+
alias inspect name
|
16
|
+
end
|
17
|
+
|
18
|
+
class DifferentialBase
|
19
|
+
attr_reader :differential_level
|
20
|
+
def initialize(level)
|
21
|
+
@differential_level = level
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"a[n-#{differential_level}]"
|
26
|
+
end
|
27
|
+
|
28
|
+
alias inspect to_s
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Unodos::Formatter
|
2
|
+
def self.format_rational(n, wrap: false)
|
3
|
+
return '0' if n == 0
|
4
|
+
return n.inspect unless n.is_a? Rational
|
5
|
+
return n.numerator.inspect if n.denominator == 1
|
6
|
+
s = "#{n.numerator.abs}/#{n.denominator}"
|
7
|
+
s = "(#{s})" if wrap
|
8
|
+
s = '-' + s if n < 0
|
9
|
+
s
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.format(n, wrap: false)
|
13
|
+
return '0' if n == 0
|
14
|
+
if n.imag == 0
|
15
|
+
format_rational n.real, wrap: wrap
|
16
|
+
elsif n.real == 0
|
17
|
+
format_rational(n.imag, wrap: true) + 'i'
|
18
|
+
else
|
19
|
+
r = format_rational(n.real)
|
20
|
+
i = format_rational(n.imag, wrap: true)
|
21
|
+
s = r + (n.imag > 0 ? '+' : '') + i + 'i'
|
22
|
+
s = "(#{s})" if wrap
|
23
|
+
s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'formatter'
|
2
|
+
require_relative 'solver'
|
3
|
+
|
4
|
+
class Unodos::Infinite < Enumerator
|
5
|
+
attr_reader :cost, :elements, :differential_level, :initial
|
6
|
+
def initialize(list)
|
7
|
+
min_cost = list.size + 1
|
8
|
+
result = nil
|
9
|
+
list.size.times do |level|
|
10
|
+
cost, res = Unodos::Solver.solve list, level, min_cost
|
11
|
+
if cost && cost < min_cost
|
12
|
+
min_cost = cost
|
13
|
+
result = res
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@cost = min_cost
|
17
|
+
@elements = result.map do |(_, _, base), v|
|
18
|
+
v = v.real.to_i if v.real.to_i == v
|
19
|
+
[base, v] if v != 0
|
20
|
+
end.compact
|
21
|
+
@differential_level = @elements.map(&:first).map(&:differential_level).max
|
22
|
+
@initial = list.take(@differential_level)
|
23
|
+
end
|
24
|
+
|
25
|
+
def rule
|
26
|
+
es = @elements.map.with_index do |(base, v), i|
|
27
|
+
sign = i != 0
|
28
|
+
name = base.to_s
|
29
|
+
s = if name == '1'
|
30
|
+
Unodos::Formatter.format v
|
31
|
+
elsif v == 1
|
32
|
+
name
|
33
|
+
elsif v == -1
|
34
|
+
'-' + name
|
35
|
+
else
|
36
|
+
Unodos::Formatter.format(v, wrap: true) + '*' + name
|
37
|
+
end
|
38
|
+
i == 0 || '-+'.include?(s[0]) ? s : '+' + s
|
39
|
+
end
|
40
|
+
"a[n]=#{es.join}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def inspect
|
44
|
+
if differential?
|
45
|
+
"[#{[*initial, rule].join(', ')}]"
|
46
|
+
else
|
47
|
+
rule
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def differential?
|
52
|
+
differential_level > 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def each(&block)
|
56
|
+
Enumerator.new do |y|
|
57
|
+
differential = [0] * differential_level
|
58
|
+
(0..).each do |i|
|
59
|
+
v = if i < differential_level
|
60
|
+
initial[i]
|
61
|
+
else
|
62
|
+
elements.sum do |base, v|
|
63
|
+
if base.differential_level > 0
|
64
|
+
v * differential[(i - base.differential_level) % differential_level]
|
65
|
+
else
|
66
|
+
v * base.proc.call(i)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
differential[i % differential_level] = v if differential?
|
71
|
+
y << v
|
72
|
+
end
|
73
|
+
end.each(&block)
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
module Unodos::Solver
|
3
|
+
TOLERANCE = 1e-12
|
4
|
+
NAMED_BASES = [
|
5
|
+
Unodos::NamedBase.new('1') { |_| 1 },
|
6
|
+
Unodos::NamedBase.new('n') { |n| n },
|
7
|
+
Unodos::NamedBase.new('n**2') { |n| n**2 },
|
8
|
+
Unodos::NamedBase.new('n**3') { |n| n**3 },
|
9
|
+
Unodos::NamedBase.new('n**4') { |n| n**4 },
|
10
|
+
Unodos::NamedBase.new('n**5') { |n| n**5 },
|
11
|
+
Unodos::NamedBase.new('2**n') { |n| 2**n },
|
12
|
+
]
|
13
|
+
|
14
|
+
def self.lup_solve(lup, b)
|
15
|
+
size = b.size
|
16
|
+
m = b.values_at(*lup.pivots)
|
17
|
+
mat_l = lup.l
|
18
|
+
mat_u = lup.u
|
19
|
+
size.times do |k|
|
20
|
+
(k + 1).upto(size - 1) do |i|
|
21
|
+
m[i] -= m[k] * mat_l[i, k]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
(size - 1).downto(0) do |k|
|
25
|
+
next if m[k] == 0
|
26
|
+
return nil if mat_u[k, k].zero?
|
27
|
+
m[k] = m[k].quo mat_u[k, k]
|
28
|
+
k.times do |i|
|
29
|
+
m[i] -= m[k] * mat_u[i, k]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
m
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.solve(list, differential_level, min_cost)
|
36
|
+
base_cost = differential_level
|
37
|
+
max_items = min_cost - base_cost - 1
|
38
|
+
return nil if max_items <= 0
|
39
|
+
result = nil
|
40
|
+
vector_max_bases = NAMED_BASES.map do |base|
|
41
|
+
vector = (differential_level..list.size-1).map do |i|
|
42
|
+
base.proc.call(i)
|
43
|
+
end
|
44
|
+
[vector, vector.map(&:abs).max, base]
|
45
|
+
end
|
46
|
+
if differential_level > 0
|
47
|
+
(1..differential_level).each do |level|
|
48
|
+
vector = list.take(list.size - level).drop(differential_level - level)
|
49
|
+
vector_max_bases.unshift [vector, vector.map(&:abs).max, Unodos::DifferentialBase.new(level)]
|
50
|
+
end
|
51
|
+
list = list.drop differential_level
|
52
|
+
end
|
53
|
+
select_solve vector_max_bases.map(&:first), list, max_items, differential_level > 0 do |vs, pos|
|
54
|
+
rs = vector_max_bases.values_at(*pos).zip(vs)
|
55
|
+
rs.each { |r| r[1] = 0 if (r[0][1] * r[1]).abs < TOLERANCE }
|
56
|
+
next if differential_level > 0 && rs[0][1] == 0
|
57
|
+
cost = rs.sum { |(_, _, base), v| v == 0 ? 0 : 1 } + base_cost
|
58
|
+
if cost < min_cost
|
59
|
+
min_cost = cost
|
60
|
+
result = rs
|
61
|
+
end
|
62
|
+
end
|
63
|
+
[min_cost, result] if result
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.match_vector(vector, bvector)
|
67
|
+
v, b = vector.zip(bvector).max_by { |a,| a.abs }
|
68
|
+
a = b.quo v
|
69
|
+
err = vector.zip(bvector).map { |v, b| (v * a - b).abs }.max
|
70
|
+
a if err < TOLERANCE
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.find_solve(vectors, bvector, &block)
|
74
|
+
(1...vectors.size).each do |i|
|
75
|
+
least_square_solve [vectors[0], vectors[i]], bvector do |vs, pos|
|
76
|
+
block.call vs, pos.map { |c| c == 1 ? i : 0 }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.select_solve(vectors, bvector, max_items, first_required, &block)
|
82
|
+
if first_required && max_items == 1
|
83
|
+
a = match_vector vectors[0], bvector
|
84
|
+
block.call [a], [0] if a
|
85
|
+
elsif vectors.size < bvector.size
|
86
|
+
least_square_solve vectors, bvector, &block
|
87
|
+
elsif first_required && max_items == 2
|
88
|
+
find_solve vectors, bvector, &block
|
89
|
+
elsif
|
90
|
+
recursive_solve vectors, bvector, first_required, &block
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.least_square_solve(vectors, bvector, &block)
|
95
|
+
mat = Matrix[*vectors.transpose]
|
96
|
+
tmat = mat.transpose
|
97
|
+
m = tmat * mat
|
98
|
+
b = tmat * Vector[*bvector]
|
99
|
+
vs = lup_solve m.lup, b.to_a
|
100
|
+
return unless vs
|
101
|
+
max_diff = bvector.each_with_index.map do |bv, i|
|
102
|
+
(vectors.zip(vs).sum { |a, v| v * a[i] } - bv).abs
|
103
|
+
end.max
|
104
|
+
block.call vs, (0...vectors.size).to_a if max_diff < TOLERANCE
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.recursive_solve(vectors, bvector, first_required, &block)
|
108
|
+
return least_square_solve vectors, bvector, &block if vectors.size < bvector.size
|
109
|
+
size = vectors.size
|
110
|
+
out_size = bvector.size
|
111
|
+
skip_size = size - out_size
|
112
|
+
lup = Matrix[*vectors.transpose].lup
|
113
|
+
mat_l = lup.l
|
114
|
+
mat_u = lup.u.to_a
|
115
|
+
bvector = bvector.values_at(*lup.pivots)
|
116
|
+
out_size.times do |k|
|
117
|
+
(k + 1).upto(out_size - 1) do |i|
|
118
|
+
bvector[i] -= bvector[k] * mat_l[i, k]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
solved = lambda do |u, selected|
|
122
|
+
b = bvector.dup
|
123
|
+
(selected.size - 1).downto 0 do |i|
|
124
|
+
j = selected[i]
|
125
|
+
next if b[i] == 0
|
126
|
+
return if u[i][j] == 0
|
127
|
+
b[i] = b[i].quo u[i][j]
|
128
|
+
i.times do |k|
|
129
|
+
b[k] -= b[i] * u[k][j]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
block.call b, selected
|
133
|
+
end
|
134
|
+
solve = lambda do |u, selected, index|
|
135
|
+
return solved.call u, selected if selected.size == out_size
|
136
|
+
j = selected.size
|
137
|
+
restore_index = (j .. [index, out_size - 1].min).max_by do |k|
|
138
|
+
u[k][index].abs
|
139
|
+
end
|
140
|
+
u[j], u[restore_index] = u[restore_index], u[j]
|
141
|
+
bvector[j], bvector[restore_index] = bvector[restore_index], bvector[j]
|
142
|
+
restore = (j + 1 .. [index, out_size - 1].min).map do |k|
|
143
|
+
v = u[j][index] == 0 ? 0 : u[k][index].quo(u[j][index])
|
144
|
+
(index + 1 ... size).each do |l|
|
145
|
+
u[k][l] -= v * u[j][l]
|
146
|
+
end
|
147
|
+
bvector[k] -= v * bvector[j]
|
148
|
+
[k, v]
|
149
|
+
end
|
150
|
+
selected.push index
|
151
|
+
solve.call u, selected, index + 1
|
152
|
+
selected.pop
|
153
|
+
restore.reverse_each do |k, v|
|
154
|
+
(index + 1 ... size).each do |l|
|
155
|
+
u[k][l] += v * u[j][l]
|
156
|
+
end
|
157
|
+
bvector[k] += v * bvector[j]
|
158
|
+
end
|
159
|
+
u[j], u[restore_index] = u[restore_index], u[j]
|
160
|
+
bvector[j], bvector[restore_index] = bvector[restore_index], bvector[j]
|
161
|
+
solve.call u, selected, index + 1 if size - index > out_size - selected.size
|
162
|
+
end
|
163
|
+
if first_required
|
164
|
+
solve.call mat_u, [0], 1
|
165
|
+
else
|
166
|
+
solve.call mat_u, [], 0
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/lib/unodos/sugar.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
class Array
|
2
|
+
def infinite(&block)
|
3
|
+
inf = Unodos::Infinite.new(self)
|
4
|
+
block ? inf.each(&block) : inf
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Unodos::Sugar
|
9
|
+
def self.target_array?(array)
|
10
|
+
last = array.last
|
11
|
+
return false unless array.size >= 2 && last.is_a?(Range) && last.end.nil?
|
12
|
+
*items, _ = array
|
13
|
+
items.all?(Numeric)
|
14
|
+
end
|
15
|
+
refine Array do
|
16
|
+
%i[each map take find_index first take_while].each do |method|
|
17
|
+
define_method method do |*args, **kwargs, &block|
|
18
|
+
if Unodos::Sugar.target_array? self
|
19
|
+
*items, last = self
|
20
|
+
Unodos::Infinite.new(items + [last.begin]).send(method, *args, **kwargs, &block)
|
21
|
+
else
|
22
|
+
super(*args, **kwargs, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/unodos.rb
ADDED
data/unodos.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'lib/unodos/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "unodos"
|
5
|
+
spec.version = Unodos::VERSION
|
6
|
+
spec.authors = ["tompng"]
|
7
|
+
spec.email = ["tomoyapenguin@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{Infinite number sequence generator}
|
10
|
+
spec.description = %q{Infinite number sequence generator}
|
11
|
+
spec.homepage = "https://github.com/tompng/unodos"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = "exe"
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unodos
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- tompng
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-30 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Infinite number sequence generator
|
14
|
+
email:
|
15
|
+
- tomoyapenguin@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- Gemfile
|
22
|
+
- Gemfile.lock
|
23
|
+
- LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- bin/console
|
27
|
+
- bin/setup
|
28
|
+
- lib/unodos.rb
|
29
|
+
- lib/unodos/base.rb
|
30
|
+
- lib/unodos/formatter.rb
|
31
|
+
- lib/unodos/infinite.rb
|
32
|
+
- lib/unodos/solver.rb
|
33
|
+
- lib/unodos/sugar.rb
|
34
|
+
- lib/unodos/version.rb
|
35
|
+
- unodos.gemspec
|
36
|
+
homepage: https://github.com/tompng/unodos
|
37
|
+
licenses:
|
38
|
+
- MIT
|
39
|
+
metadata:
|
40
|
+
homepage_uri: https://github.com/tompng/unodos
|
41
|
+
source_code_uri: https://github.com/tompng/unodos
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.3.0
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubygems_version: 3.1.2
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Infinite number sequence generator
|
61
|
+
test_files: []
|