compsci 0.3.1.1 → 0.3.2.1
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/README.md +3 -3
- data/VERSION +1 -1
- data/compsci.gemspec +3 -3
- data/lib/compsci/fit.rb +17 -0
- data/lib/compsci/names/pokemon.rb +2 -2
- data/lib/compsci/simplex/parse.rb +6 -2
- data/lib/compsci/simplex.rb +17 -16
- data/lib/compsci/timer.rb +61 -1
- data/test/fit.rb +54 -16
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a7f1f7282649dec4f08ef08ce3eb3b5b3b97183137624deaa9f20567650185a
|
4
|
+
data.tar.gz: 57081ef332e9adc6d3dbdc06b3ff2c9c76955d26b4fdd90402b7547b5544e0fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdb60b8e1230cdc175ac43afca1efe51bb163ce71dfb2cdd29ffa8ff8ab586456ec181dd46389d54b768edb360f5f9f56d6729bbd65ee86fcd7fa7acee0f417e
|
7
|
+
data.tar.gz: 3f20b69bd337aebc862a7f40e1e1177386979f71065200fa18e4dd69bdefb3a382dd8cbd066903d2ba5793cf5c71acd9cd09b79088c4c15b38982b8196bfb0c2
|
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
[](https://github.com/rickhull/compsci/actions/workflows/ci.yaml)
|
2
2
|
[](https://badge.fury.io/rb/compsci)
|
3
|
-
[](https://gemnasium.com/rickhull/compsci)
|
4
|
-
[](https://hakiri.io/github/rickhull/compsci/master)
|
5
3
|
|
6
4
|
# CompSci
|
7
5
|
|
@@ -213,6 +211,8 @@ alphabetical order.
|
|
213
211
|
|
214
212
|
## [`Simplex`](lib/compsci/simplex.rb) class
|
215
213
|
|
214
|
+
### WORK IN PROGRESS; DO NOT USE
|
215
|
+
|
216
216
|
The [Simplex algorithm](https://en.wikipedia.org/wiki/Simplex_algorithm)
|
217
217
|
is a technique for
|
218
218
|
[Linear programming](https://en.wikipedia.org/wiki/Linear_programming).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2.1
|
data/compsci.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.homepage = "https://github.com/rickhull/compsci"
|
7
7
|
s.license = "LGPL-3.0"
|
8
8
|
|
9
|
-
s.required_ruby_version = "~>
|
9
|
+
s.required_ruby_version = "~> 3.0"
|
10
10
|
|
11
11
|
s.version = File.read(File.join(__dir__, 'VERSION')).chomp
|
12
12
|
|
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.files += Dir['examples/**/*.rb']
|
17
17
|
|
18
18
|
s.add_development_dependency "buildar", "~> 3.0"
|
19
|
-
s.add_development_dependency "minitest", "
|
20
|
-
s.add_development_dependency "rake", "
|
19
|
+
s.add_development_dependency "minitest", "~> 5.0"
|
20
|
+
s.add_development_dependency "rake", "~> 12.3" # CVE-2020-8130
|
21
21
|
s.add_development_dependency "flog", "~> 0"
|
22
22
|
s.add_development_dependency "flay", "~> 0"
|
23
23
|
s.add_development_dependency "roodi", "~> 0"
|
data/lib/compsci/fit.rb
CHANGED
@@ -153,5 +153,22 @@ module CompSci
|
|
153
153
|
|
154
154
|
return Math.exp(a), b, self.error(xys) { |x| (Math.exp(a) * (x ** b)) }
|
155
155
|
end
|
156
|
+
|
157
|
+
def self.predict(model, a, b, x)
|
158
|
+
case model
|
159
|
+
when :constant
|
160
|
+
a
|
161
|
+
when :logarithmic
|
162
|
+
a + b * Math.log(x)
|
163
|
+
when :linear
|
164
|
+
a + b * x
|
165
|
+
when :exponential
|
166
|
+
a * Math::E ** (b * x)
|
167
|
+
when :power
|
168
|
+
a * x ** b
|
169
|
+
else
|
170
|
+
raise("unknown model: #{model}")
|
171
|
+
end
|
172
|
+
end
|
156
173
|
end
|
157
174
|
end
|
@@ -34,8 +34,8 @@ module CompSci::Names::Pokemon
|
|
34
34
|
# a hash of all the names, keyed by the first letter
|
35
35
|
def self.read_hash(path: DATAFILE)
|
36
36
|
hsh = Hash.new { |h, k| h[k] = [] }
|
37
|
-
File.open(path).each_line { |
|
38
|
-
hsh[
|
37
|
+
File.open(path).each_line { |line|
|
38
|
+
hsh[line.chr] << line.chomp
|
39
39
|
}
|
40
40
|
hsh
|
41
41
|
end
|
@@ -82,7 +82,11 @@ class CompSci::Simplex
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
def self.problem(
|
85
|
+
def self.problem(**kwargs)
|
86
|
+
self.new(*self.get_params(**kwargs))
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.get_params(maximize: nil, constraints: [], **kwargs)
|
86
90
|
if maximize
|
87
91
|
expr, maximize = maximize, true
|
88
92
|
elsif kwargs[:minimize]
|
@@ -116,7 +120,7 @@ class CompSci::Simplex
|
|
116
120
|
a.push cofs
|
117
121
|
b.push rhs
|
118
122
|
}
|
119
|
-
|
123
|
+
[c, a, b]
|
120
124
|
end
|
121
125
|
|
122
126
|
def self.maximize(expression, *ineqs)
|
data/lib/compsci/simplex.rb
CHANGED
@@ -26,35 +26,36 @@ class CompSci::Simplex
|
|
26
26
|
@max_pivots = DEFAULT_MAX_PIVOTS
|
27
27
|
|
28
28
|
# Problem dimensions; these never change
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
29
|
+
@num_free_vars = num_vars
|
30
|
+
@num_basic_vars = num_inequalities
|
31
|
+
@total_vars = @num_free_vars + @num_basic_vars
|
32
32
|
|
33
33
|
# Set up initial matrix A and vectors b, c
|
34
|
-
|
34
|
+
# store all input values as Rational (via #rationalize)
|
35
|
+
@c = c.map { |flt| -1 * flt.rationalize } + Array.new(@num_basic_vars, 0)
|
35
36
|
@a = a.map.with_index { |ary, i|
|
36
|
-
if ary.size != @
|
37
|
+
if ary.size != @num_free_vars
|
37
38
|
raise ArgumentError, "a is inconsistent"
|
38
39
|
end
|
39
|
-
#
|
40
|
-
ary
|
40
|
+
# add identity matrix
|
41
|
+
ary.map { |flt| flt.rationalize } +
|
42
|
+
Array.new(@num_basic_vars) { |ci| ci == i ? 1 : 0 }
|
41
43
|
}
|
42
|
-
@b = b
|
44
|
+
@b = b.map { |flt| flt.rationalize }
|
43
45
|
|
44
|
-
|
45
|
-
@basic_vars = (@num_non_slack_vars...@num_vars).to_a
|
46
|
+
@basic_vars = (@num_free_vars...@total_vars).to_a
|
46
47
|
self.update_solution
|
47
48
|
end
|
48
49
|
|
49
50
|
# does not modify vector / matrix
|
50
51
|
def update_solution
|
51
|
-
@x = Array.new(@
|
52
|
+
@x = Array.new(@total_vars, 0)
|
52
53
|
|
53
54
|
@basic_vars.each { |basic_var|
|
54
55
|
idx = nil
|
55
|
-
@
|
56
|
+
@num_basic_vars.times { |i|
|
56
57
|
if @a[i][basic_var] == 1
|
57
|
-
idx =i
|
58
|
+
idx = i
|
58
59
|
break
|
59
60
|
end
|
60
61
|
}
|
@@ -78,7 +79,7 @@ class CompSci::Simplex
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def current_solution
|
81
|
-
@x[0...@
|
82
|
+
@x[0...@num_free_vars]
|
82
83
|
end
|
83
84
|
|
84
85
|
def can_improve?
|
@@ -121,7 +122,7 @@ class CompSci::Simplex
|
|
121
122
|
}
|
122
123
|
|
123
124
|
# update A and B
|
124
|
-
@
|
125
|
+
@num_basic_vars.times { |i|
|
125
126
|
next if i == pivot_row
|
126
127
|
r = @a[i][pivot_column]
|
127
128
|
@a[i] = @a[i].map.with_index { |val, j| val - r * @a[pivot_row][j] }
|
@@ -134,7 +135,7 @@ class CompSci::Simplex
|
|
134
135
|
def pivot_row(column_ix)
|
135
136
|
min_ratio = nil
|
136
137
|
idx = nil
|
137
|
-
@
|
138
|
+
@num_basic_vars.times { |i|
|
138
139
|
a, b = @a[i][column_ix], @b[i]
|
139
140
|
next if a == 0 or (b < 0) ^ (a < 0)
|
140
141
|
ratio = Rational(b, a)
|
data/lib/compsci/timer.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
module CompSci
|
2
|
-
|
2
|
+
class Timer
|
3
|
+
SECS_PER_MIN = 60
|
4
|
+
MINS_PER_HOUR = 60
|
5
|
+
SECS_PER_HOUR = SECS_PER_MIN * MINS_PER_HOUR
|
6
|
+
|
3
7
|
# lifted from seattlerb/minitest
|
4
8
|
if defined? Process::CLOCK_MONOTONIC
|
5
9
|
def self.now
|
@@ -32,5 +36,61 @@ module CompSci
|
|
32
36
|
}
|
33
37
|
return val, self.since(start) / i.to_f
|
34
38
|
end
|
39
|
+
|
40
|
+
# YYYY-MM-DD HH::MM::SS.mmm
|
41
|
+
def self.timestamp(t)
|
42
|
+
t.strftime "%Y-%m-%d %H:%M:%S.%L"
|
43
|
+
end
|
44
|
+
|
45
|
+
# HH::MM::SS.mmm.uuuuuuuu
|
46
|
+
def self.elapsed_display(elapsed_ms, show_us: false)
|
47
|
+
elapsed_s, ms = elapsed_ms.divmod 1000
|
48
|
+
ms_only, ms_fraction = ms.round(8).divmod 1
|
49
|
+
|
50
|
+
h = elapsed_s / SECS_PER_HOUR
|
51
|
+
elapsed_s -= h * SECS_PER_HOUR
|
52
|
+
m, s = elapsed_s.divmod SECS_PER_MIN
|
53
|
+
|
54
|
+
hmsms = [[h, m, s].map { |i| i.to_s.rjust(2, '0') }.join(':'),
|
55
|
+
ms_only.to_s.rjust(3, '0')]
|
56
|
+
hmsms << (ms_fraction * 10 ** 8).round.to_s.ljust(8, '0') if show_us
|
57
|
+
hmsms.join('.')
|
58
|
+
end
|
59
|
+
|
60
|
+
def restart(t = Time.now)
|
61
|
+
@start = t
|
62
|
+
self
|
63
|
+
end
|
64
|
+
alias_method :initialize, :restart
|
65
|
+
|
66
|
+
def timestamp(t = Time.now)
|
67
|
+
self.class.timestamp t
|
68
|
+
end
|
69
|
+
|
70
|
+
def timestamp!(t = Time.now)
|
71
|
+
puts '-' * 70, timestamp(t), '-' * 70
|
72
|
+
end
|
73
|
+
|
74
|
+
def elapsed(t = Time.now)
|
75
|
+
t - @start
|
76
|
+
end
|
77
|
+
|
78
|
+
def elapsed_ms(t = Time.now)
|
79
|
+
elapsed(t) * 1000
|
80
|
+
end
|
81
|
+
|
82
|
+
def elapsed_display(t = Time.now)
|
83
|
+
self.class.elapsed_display(elapsed_ms(t))
|
84
|
+
end
|
85
|
+
alias_method :to_s, :elapsed_display
|
86
|
+
alias_method :inspect, :elapsed_display
|
87
|
+
|
88
|
+
def stamp(msg = '', t = Time.now)
|
89
|
+
format("%s %s", elapsed_display(t), msg)
|
90
|
+
end
|
91
|
+
|
92
|
+
def stamp!(msg = '', t = Time.now)
|
93
|
+
puts stamp(msg, t)
|
94
|
+
end
|
35
95
|
end
|
36
96
|
end
|
data/test/fit.rb
CHANGED
@@ -15,14 +15,14 @@ describe Fit do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
describe "Fit.sigma" do
|
18
|
-
it "
|
18
|
+
it "answers correctly" do
|
19
19
|
expect(Fit.sigma([1, 2, 3])).must_equal 6
|
20
20
|
expect(Fit.sigma([1, 2, 3]) { |n| n ** 2 }).must_equal 14
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "Fit.error" do
|
25
|
-
it "
|
25
|
+
it "calculates r^2" do
|
26
26
|
expect(Fit.error([[1, 1], [2, 2], [3, 3]]) { |x| x }).must_equal 1.0
|
27
27
|
expect(Fit.error([[1, 1], [2, 2], [3, 4]]) { |x|
|
28
28
|
x
|
@@ -36,7 +36,7 @@ describe Fit do
|
|
36
36
|
# alternate measure. A low slope and r2 for linear fit, maybe.
|
37
37
|
#
|
38
38
|
describe "Fit.constant" do
|
39
|
-
it "
|
39
|
+
it "returns zero variance with truly constant inputs" do
|
40
40
|
[0, 1, 10, 100, 1000, 9999].each { |a|
|
41
41
|
y_bar, variance = Fit.constant(@xs, @xs.map { |x| a })
|
42
42
|
expect(y_bar).must_equal a
|
@@ -47,7 +47,7 @@ describe Fit do
|
|
47
47
|
|
48
48
|
# y = a + b*ln(x)
|
49
49
|
describe "Fit.logarithmic" do
|
50
|
-
it "
|
50
|
+
it "accepts logarithmic data" do
|
51
51
|
[-9999, -2000, -500, -0.01, 0.01, 500, 2000, 9999].each { |a|
|
52
52
|
[-9999, -2000, -500, -0.01, 0.01, 500, 2000, 9999].each { |b|
|
53
53
|
ary = Fit.logarithmic(@xs, @xs.map { |x| a + b * Math.log(x) })
|
@@ -61,7 +61,7 @@ describe Fit do
|
|
61
61
|
|
62
62
|
# y = a + bx
|
63
63
|
describe "Fit.linear" do
|
64
|
-
it "
|
64
|
+
it "accepts linear data" do
|
65
65
|
[-9999, -2000, -500, -0.01, 0.01, 500, 2000, 9999].each { |a|
|
66
66
|
[-9999, -2000, -500, -0.01, 0.01, 500, 2000, 9999].each { |b|
|
67
67
|
ary = Fit.linear(@xs, @xs.map { |x| a + b * x })
|
@@ -72,7 +72,7 @@ describe Fit do
|
|
72
72
|
}
|
73
73
|
end
|
74
74
|
|
75
|
-
it "
|
75
|
+
it "accepts constant data" do
|
76
76
|
[0, 1, 10, 100, 1000, 9999].each { |a|
|
77
77
|
ary = Fit.linear(@xs, @xs.map { |x| a })
|
78
78
|
expect(ary[0]).must_equal a
|
@@ -84,7 +84,7 @@ describe Fit do
|
|
84
84
|
# note, this test can possibly fail depending on the uniformity of
|
85
85
|
# rand's output for our sample
|
86
86
|
#
|
87
|
-
it "
|
87
|
+
it "accepts noisy constant data" do
|
88
88
|
r2s = []
|
89
89
|
[0, 1, 10, 100, 1000, 9999].each { |a|
|
90
90
|
ary = Fit.linear(@xs, @xs.map { |x| a + noise() })
|
@@ -96,16 +96,14 @@ describe Fit do
|
|
96
96
|
expect(mean_r2).must_be_close_to 0.15, 0.15
|
97
97
|
end
|
98
98
|
|
99
|
-
it "
|
100
|
-
|
101
|
-
xs = [1, 10, 100, 1000]
|
99
|
+
it "rejects x^2" do
|
100
|
+
xs = Array.new(99) { |i| i }
|
102
101
|
_a, _b, r2 = Fit.linear(xs, xs.map { |x| x**2 })
|
103
102
|
expect(r2).must_be :<, 0.99
|
104
103
|
end
|
105
104
|
|
106
|
-
it "
|
107
|
-
|
108
|
-
xs = [1, 10, 100, 1000]
|
105
|
+
it "rejects x^3" do
|
106
|
+
xs = Array.new(99) { |i| i }
|
109
107
|
_a, _b, r2 = Fit.linear(xs, xs.map { |x| x**3 })
|
110
108
|
expect(r2).must_be :<, 0.99
|
111
109
|
end
|
@@ -113,7 +111,7 @@ describe Fit do
|
|
113
111
|
|
114
112
|
# y = ae^(bx)
|
115
113
|
describe "Fit.exponential" do
|
116
|
-
it "
|
114
|
+
it "accepts exponential data" do
|
117
115
|
[0.001, 7.5, 500, 1000, 5000, 9999].each { |a|
|
118
116
|
[-1.4, -1.1, -0.1, 0.01, 0.5, 0.75].each { |b|
|
119
117
|
ary = Fit.exponential(@xs, @xs.map { |x| a * Math::E**(b * x) })
|
@@ -127,10 +125,13 @@ describe Fit do
|
|
127
125
|
|
128
126
|
# y = ax^b
|
129
127
|
describe "Fit.power" do
|
130
|
-
it "
|
128
|
+
it "accepts power data" do
|
131
129
|
[0.01, 7.5, 500, 1000, 5000, 9999].each { |a|
|
132
130
|
[-114, -100, -10, -0.5, -0.1, 0.1, 0.75, 10, 50, 60].each { |b|
|
133
|
-
|
131
|
+
# [ -100, -10, -0.5, -0.1, 0.1, 0.75, 10, 50, 60].each { |b|
|
132
|
+
# note: on Ruby 2.4.x and older, b == -114 throws
|
133
|
+
# warning: Bignum out of Float range
|
134
|
+
# also: TruffleRuby as of Jan '22: ary[2] is NaN rather than 1.0
|
134
135
|
ary = Fit.power(@xs, @xs.map { |x| a * x**b })
|
135
136
|
expect(ary[0]).must_be_close_to a
|
136
137
|
expect(ary[1]).must_be_close_to b
|
@@ -139,4 +140,41 @@ describe Fit do
|
|
139
140
|
}
|
140
141
|
end
|
141
142
|
end
|
143
|
+
|
144
|
+
describe "Fit.predict" do
|
145
|
+
before do
|
146
|
+
@a, @b, @x = 1, 2, 3
|
147
|
+
end
|
148
|
+
|
149
|
+
it "accepts a few different models" do
|
150
|
+
[:constant, :logarithmic, :linear, :exponential, :power].each { |model|
|
151
|
+
expect(Fit.predict(model, @a, @b, @x)).must_be_kind_of(Numeric)
|
152
|
+
}
|
153
|
+
expect { Fit.predict(:invalid, @a, @b, @x) }.must_raise RuntimeError
|
154
|
+
end
|
155
|
+
|
156
|
+
it "predicts constant relationships" do
|
157
|
+
expect(Fit.predict(:constant, @a, @b, @x)).must_equal @a
|
158
|
+
expect(Fit.predict(:constant, @a, @x, @b)).must_equal @a
|
159
|
+
expect(Fit.predict(:constant, @x, @a, @b)).must_equal @x
|
160
|
+
end
|
161
|
+
|
162
|
+
it "predicts logarithmic relationships" do
|
163
|
+
expect(Fit.predict(:logarithmic, @a, @b, @x)
|
164
|
+
).must_equal @a + @b * Math.log(@x)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "predicts linear relationships" do
|
168
|
+
expect(Fit.predict(:linear, @a, @b, @x)).must_equal @a + @b * @x
|
169
|
+
end
|
170
|
+
|
171
|
+
it "predicts exponential relationships" do
|
172
|
+
expect(Fit.predict(:exponential, @a, @b, @x)
|
173
|
+
).must_equal @a * Math::E ** (@b * @x)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "predicts power relationships" do
|
177
|
+
expect(Fit.predict(:power, @a, @b, @x)).must_equal @a * @x ** @b
|
178
|
+
end
|
179
|
+
end
|
142
180
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: compsci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: buildar
|
@@ -28,30 +28,30 @@ dependencies:
|
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '5.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 12.3
|
47
|
+
version: '12.3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 12.3
|
54
|
+
version: '12.3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: flog
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '2.0'
|
125
125
|
description: Trees, Heaps, Timers, Error fitting, etc
|
126
|
-
email:
|
126
|
+
email:
|
127
127
|
executables: []
|
128
128
|
extensions: []
|
129
129
|
extra_rdoc_files: []
|
@@ -172,7 +172,7 @@ homepage: https://github.com/rickhull/compsci
|
|
172
172
|
licenses:
|
173
173
|
- LGPL-3.0
|
174
174
|
metadata: {}
|
175
|
-
post_install_message:
|
175
|
+
post_install_message:
|
176
176
|
rdoc_options: []
|
177
177
|
require_paths:
|
178
178
|
- lib
|
@@ -180,15 +180,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
180
180
|
requirements:
|
181
181
|
- - "~>"
|
182
182
|
- !ruby/object:Gem::Version
|
183
|
-
version: '
|
183
|
+
version: '3.0'
|
184
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
186
|
- - ">="
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '0'
|
189
189
|
requirements: []
|
190
|
-
rubygems_version: 3.
|
191
|
-
signing_key:
|
190
|
+
rubygems_version: 3.2.26
|
191
|
+
signing_key:
|
192
192
|
specification_version: 4
|
193
193
|
summary: Toy implementations for some basic computer science problems
|
194
194
|
test_files: []
|