numeron 1.1.0 → 1.2.0
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.
- data/lib/numeron/calculator.rb +65 -3
- data/lib/numeron/solver.rb +33 -1
- data/lib/numeron/version.rb +1 -1
- data/numeron.gemspec +1 -1
- data/spec/lib/numeron/calculator_spec.rb +44 -0
- metadata +3 -3
data/lib/numeron/calculator.rb
CHANGED
@@ -2,18 +2,38 @@
|
|
2
2
|
|
3
3
|
module Numeron
|
4
4
|
class Calculator
|
5
|
-
|
5
|
+
# コール履歴
|
6
|
+
attr_accessor :histories
|
7
|
+
# 解として可能性があるデータリスト
|
8
|
+
attr_accessor :possibilities
|
9
|
+
# 各桁における解の可能性として考えられる数値
|
10
|
+
attr_accessor :mays
|
11
|
+
# 解の桁数(未実装)
|
12
|
+
attr_accessor :answer_size
|
13
|
+
# Slash Number
|
14
|
+
attr_accessor :slash_number
|
6
15
|
|
7
|
-
def initialize(
|
16
|
+
def initialize(answer_size = 3)
|
8
17
|
@histories = []
|
9
|
-
@mays = [(0..9).to_a, (0..9).to_a, (0..9).to_a]
|
10
18
|
@possibilities = nil
|
19
|
+
@mays = [(0..9).to_a, (0..9).to_a, (0..9).to_a]
|
20
|
+
@answer_size = answer_size
|
11
21
|
end
|
12
22
|
|
23
|
+
# コールした数値とその結果を設定
|
24
|
+
# @param [String] attack コールした数値
|
25
|
+
# @param [Integer] eat Eatの数
|
26
|
+
# @param [Integer] bite Biteの数
|
27
|
+
# @return [Boolean]
|
13
28
|
def input(attack, eat, bite)
|
14
29
|
attack = attack.split(//).map(&:to_i)
|
15
30
|
eat = eat.to_i
|
16
31
|
bite = bite.to_i
|
32
|
+
|
33
|
+
if attack.size != @answer_size || eat > @answer_size || bite > @answer_size && eat + bite > @answer_size
|
34
|
+
raise ArgumentError, 'Invalid argument. '
|
35
|
+
end
|
36
|
+
|
17
37
|
@histories << {attack: attack, eat: eat, bite: bite}
|
18
38
|
|
19
39
|
if eat == 0 && bite == 0
|
@@ -32,12 +52,15 @@ module Numeron
|
|
32
52
|
one_eat_zero_bite(attack)
|
33
53
|
elsif eat == 2 && bite == 0
|
34
54
|
two_eat_zero_bite(attack)
|
55
|
+
elsif eat == 3 && bite == 0
|
56
|
+
@possibilities = []
|
35
57
|
else
|
36
58
|
return false
|
37
59
|
end
|
38
60
|
return true
|
39
61
|
end
|
40
62
|
|
63
|
+
# 0 Eat 0 Bite の時の可能性計算
|
41
64
|
def zero_eat_zero_bite(attack)
|
42
65
|
@mays[0] = @mays[0] - attack
|
43
66
|
@mays[1] = @mays[1] - attack
|
@@ -56,6 +79,7 @@ module Numeron
|
|
56
79
|
update_possibilities(list)
|
57
80
|
end
|
58
81
|
|
82
|
+
# 0 Eat 1 Bite の時の可能性計算
|
59
83
|
def zero_eat_one_bite(attack)
|
60
84
|
# 各桁のeatの可能性がなくなる
|
61
85
|
@mays[0] = @mays[0] - [attack[0]]
|
@@ -89,6 +113,7 @@ module Numeron
|
|
89
113
|
update_possibilities(list)
|
90
114
|
end
|
91
115
|
|
116
|
+
# 0 Eat 2 Bite の時の可能性計算
|
92
117
|
def zero_eat_two_bite(attack)
|
93
118
|
@mays[0] = @mays[0] - [attack[0]]
|
94
119
|
@mays[1] = @mays[1] - [attack[1]]
|
@@ -118,6 +143,7 @@ module Numeron
|
|
118
143
|
update_possibilities(list)
|
119
144
|
end
|
120
145
|
|
146
|
+
# 0 Eat 3 Bite の時の可能性計算
|
121
147
|
def zero_eat_three_bite(attack)
|
122
148
|
# 各桁の可能性が2つに絞られる
|
123
149
|
@mays[0] = @mays[0] & [attack[1], attack[2]]
|
@@ -130,6 +156,7 @@ module Numeron
|
|
130
156
|
update_possibilities(list)
|
131
157
|
end
|
132
158
|
|
159
|
+
# 1 Eat 0 Bite の時の可能性計算
|
133
160
|
def one_eat_zero_bite(attack)
|
134
161
|
list = []
|
135
162
|
# 先頭eat
|
@@ -158,6 +185,7 @@ module Numeron
|
|
158
185
|
update_possibilities(list)
|
159
186
|
end
|
160
187
|
|
188
|
+
# 1 Eat 1 Bite の時の可能性計算
|
161
189
|
def one_eat_one_bite(attack)
|
162
190
|
list = []
|
163
191
|
(@mays[2] - attack).each do |f|
|
@@ -183,6 +211,7 @@ module Numeron
|
|
183
211
|
update_possibilities(list)
|
184
212
|
end
|
185
213
|
|
214
|
+
# 1 Eat 2 Bite の時の可能性計算
|
186
215
|
def one_eat_two_bite(attack)
|
187
216
|
# attack以外の可能性がなくなるので、積
|
188
217
|
@mays[0] = @mays[0] & attack
|
@@ -196,6 +225,7 @@ module Numeron
|
|
196
225
|
update_possibilities(list)
|
197
226
|
end
|
198
227
|
|
228
|
+
# 2 Eat 0 Bite の時の可能性計算
|
199
229
|
def two_eat_zero_bite(attack)
|
200
230
|
# 先頭2つがeat
|
201
231
|
list = []
|
@@ -213,6 +243,9 @@ module Numeron
|
|
213
243
|
update_possibilities(list)
|
214
244
|
end
|
215
245
|
|
246
|
+
# 各桁が可能性としてありえるかのチェック
|
247
|
+
# @maysに含まれていること、重複がなければ正常と判定する
|
248
|
+
# @return [String, nil] 正常な場合はString, 異常値の場合は nil
|
216
249
|
def validation(i, j, k)
|
217
250
|
return nil if i == j || i == k || j == k
|
218
251
|
if @mays[0].include?(i) && @mays[1].include?(j) && @mays[2].include?(k)
|
@@ -248,6 +281,8 @@ module Numeron
|
|
248
281
|
end
|
249
282
|
end
|
250
283
|
|
284
|
+
# シャッフル時の再計算
|
285
|
+
# 1 Eat 0 Bite または 0 Eat 1 Biteの場合
|
251
286
|
def one_eat_or_one_bite(attack)
|
252
287
|
list = []
|
253
288
|
# attack[0] - attack[3]が一桁目に含まれている
|
@@ -278,6 +313,8 @@ module Numeron
|
|
278
313
|
update_possibilities(list)
|
279
314
|
end
|
280
315
|
|
316
|
+
# シャッフル時の再計算
|
317
|
+
# 2 eat 0 Bite, or 1 Eat 1 Bite or 0 Eat 0 Biteの場合
|
281
318
|
def two_eat_or_two_bite(attack)
|
282
319
|
list = []
|
283
320
|
# 末尾が不明
|
@@ -312,6 +349,31 @@ module Numeron
|
|
312
349
|
update_possibilities(list)
|
313
350
|
end
|
314
351
|
|
352
|
+
def slash(slash_number)
|
353
|
+
@slash_number = slash_number
|
354
|
+
|
355
|
+
# 9
|
356
|
+
# [0, 9]
|
357
|
+
list = []
|
358
|
+
slash_number.upto(9){|i|
|
359
|
+
min = i - slash_number
|
360
|
+
from = min + 1
|
361
|
+
to = i - 1
|
362
|
+
(from..to).to_a.each do |f|
|
363
|
+
list << validation(i, min, f)
|
364
|
+
list << validation(min, i, f)
|
365
|
+
list << validation(i, f, min)
|
366
|
+
list << validation(min, f, i)
|
367
|
+
list << validation(f, min, i)
|
368
|
+
list << validation(f, i, min)
|
369
|
+
end
|
370
|
+
}
|
371
|
+
update_possibilities(list)
|
372
|
+
end
|
373
|
+
|
374
|
+
# 可能性リストの更新
|
375
|
+
# 現在設定されている可能性リストと引数で渡された可能性リストの論理積をとる
|
376
|
+
# @param [Array] possibilities 可能性としてありえる数値リスト
|
315
377
|
def update_possibilities(possibilities)
|
316
378
|
possibilities.compact!
|
317
379
|
@possibilities = @possibilities.nil? ? possibilities : possibilities & @possibilities
|
data/lib/numeron/solver.rb
CHANGED
@@ -2,20 +2,52 @@
|
|
2
2
|
|
3
3
|
module Numeron
|
4
4
|
class Solver
|
5
|
-
attr_accessor :calc, :card_size
|
5
|
+
attr_accessor :calc, :card_size, :used_items
|
6
6
|
def initialize
|
7
7
|
@calc = Numeron::Calculator.new
|
8
8
|
@card_size = 3
|
9
|
+
@used_items = {slash: false, shuffle: false}
|
9
10
|
end
|
10
11
|
|
11
12
|
def run
|
12
13
|
while 1
|
14
|
+
item
|
13
15
|
next unless question
|
14
16
|
think
|
15
17
|
finish
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
# アイテムの使用
|
22
|
+
def item
|
23
|
+
shuffle unless @used_items[:shuffle]
|
24
|
+
slash unless @used_items[:slash]
|
25
|
+
end
|
26
|
+
|
27
|
+
def slash
|
28
|
+
print "\nUsing slash? [yes]"
|
29
|
+
f = STDIN.gets.chomp
|
30
|
+
return if f != 'yes' && f != 'y'
|
31
|
+
while 1
|
32
|
+
print "Input slash number: "
|
33
|
+
f =STDIN.gets.chomp.to_i
|
34
|
+
break if f >= 2 && f <= 9
|
35
|
+
puts "Invalid slash number."
|
36
|
+
end
|
37
|
+
@calc.slash(f)
|
38
|
+
@used_items[:slash] = true
|
39
|
+
think
|
40
|
+
end
|
41
|
+
|
42
|
+
def shuffle
|
43
|
+
print "\nUsing shuffle? [yes]"
|
44
|
+
f = STDIN.gets.chomp
|
45
|
+
return if f != 'yes' && f != 'y'
|
46
|
+
@calc.shuffle
|
47
|
+
@used_items[:shuffle] = true
|
48
|
+
think
|
49
|
+
end
|
50
|
+
|
19
51
|
def question
|
20
52
|
attack_number = nil
|
21
53
|
eat = 0
|
data/lib/numeron/version.rb
CHANGED
data/numeron.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Numeron::VERSION
|
9
9
|
gem.authors = ["kengos"]
|
10
10
|
gem.email = ["kengo@kengos.jp"]
|
11
|
-
gem.description = %q{numer0nの解を計算します。(Shuffle
|
11
|
+
gem.description = %q{numer0nの解を計算します。(Shuffle, Slash対応, シミュレーター付き, Analyzer未完成)}
|
12
12
|
gem.summary = %q{numer0n solver}
|
13
13
|
gem.homepage = "https://github.com/kengos/numeron"
|
14
14
|
|
@@ -78,6 +78,50 @@ describe Numeron::Calculator do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
describe '#slash' do
|
82
|
+
# slashを使った場合は、解の可能性は 6 * (10 - n) * (n - 1)に絞られる
|
83
|
+
# 正しくは、 s! * (10 - n) * (n - s + 2) (sはカードの枚数、 nはslash number, s!はsの階乗)
|
84
|
+
it 'slash 2' do
|
85
|
+
calc.slash(2)
|
86
|
+
calc.possibilities.should have(48).items
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'slash 3' do
|
90
|
+
calc.slash(3)
|
91
|
+
calc.possibilities.should have(84).items
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'slash 4' do
|
95
|
+
calc.slash(4)
|
96
|
+
calc.possibilities.should have(108).items
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'slash 5' do
|
100
|
+
calc.slash(5)
|
101
|
+
calc.possibilities.should have(120).items
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'slash 6' do
|
105
|
+
calc.slash(6)
|
106
|
+
calc.possibilities.should have(120).items
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'slash 7' do
|
110
|
+
calc.slash(7)
|
111
|
+
calc.possibilities.should have(108).items
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'slash 8' do
|
115
|
+
calc.slash(8)
|
116
|
+
calc.possibilities.should have(84).items
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'slash 9' do
|
120
|
+
calc.slash(9)
|
121
|
+
calc.possibilities.should have(48).items
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
81
125
|
describe "scenario" do
|
82
126
|
it "1e0b, 1e2b" do
|
83
127
|
calc.input('348', 1, 0)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numeron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,9 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description: numer0nの解を計算します。(Shuffle
|
14
|
+
description: numer0nの解を計算します。(Shuffle, Slash対応, シミュレーター付き, Analyzer未完成)
|
15
15
|
email:
|
16
16
|
- kengo@kengos.jp
|
17
17
|
executables: []
|