Class: Numeron::Calculator

Inherits:
Object
  • Object
show all
Defined in:
lib/numeron/calculator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(card_size = 3) ⇒ Calculator

Returns a new instance of Calculator.



7
8
9
10
11
# File 'lib/numeron/calculator.rb', line 7

def initialize(card_size = 3)
  @histories = []
  @mays = [(0..9).to_a, (0..9).to_a, (0..9).to_a]
  @possibilities = nil
end

Instance Attribute Details

#historiesObject

Returns the value of attribute histories.



5
6
7
# File 'lib/numeron/calculator.rb', line 5

def histories
  @histories
end

#maysObject

Returns the value of attribute mays.



5
6
7
# File 'lib/numeron/calculator.rb', line 5

def mays
  @mays
end

#possibilitiesObject

Returns the value of attribute possibilities.



5
6
7
# File 'lib/numeron/calculator.rb', line 5

def possibilities
  @possibilities
end

Instance Method Details

#input(attack, eat, bite) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/numeron/calculator.rb', line 13

def input(attack, eat, bite)
  attack = attack.split(//).map(&:to_i)
  eat = eat.to_i
  bite = bite.to_i
  @histories << {attack: attack, eat: eat, bite: bite}

  if eat == 0 && bite == 0
    zero_eat_zero_bite(attack)
  elsif eat == 0 && bite == 3
    zero_eat_three_bite(attack)
  elsif eat == 0 && bite == 2
    zero_eat_two_bite(attack)
  elsif eat == 0 && bite == 1
    zero_eat_one_bite(attack)
  elsif eat == 1 && bite == 2
    one_eat_two_bite(attack)
  elsif eat == 1 && bite == 1
    one_eat_one_bite(attack)
  elsif eat == 1 && bite == 0
    one_eat_zero_bite(attack)
  elsif eat == 2 && bite == 0
    two_eat_zero_bite(attack)
  else
    return false
  end
  return true
end

#one_eat_one_bite(attack) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/numeron/calculator.rb', line 161

def one_eat_one_bite(attack)
  list = []
  (@mays[2] - attack).each do |f|
    list << validation(attack[0], attack[2], f)
  end
  (@mays[1] - attack).each do |f|
    list << validation(attack[0], f, attack[1])
  end
  # 2桁目があっている
  (@mays[2] - attack).each do |f|
    list << validation(attack[2], attack[1], f)
  end
  (@mays[0] - attack).each do |f|
    list << validation(f, attack[1], attack[0])
  end
  # 3桁目があっている
  (@mays[0] - attack).each do |f|
    list << validation(f, attack[0], attack[2])
  end
  (@mays[1] - attack).each do |f|
    list << validation(attack[1], f, attack[2])
  end
  update_possibilities(list)
end

#one_eat_or_one_bite(attack) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/numeron/calculator.rb', line 251

def one_eat_or_one_bite(attack)
  list = []
  # attack[0] - attack[3]が一桁目に含まれている
  (@mays[1] - attack).each do |j|
    (@mays[2] - attack).each do |k|
      next if j == k
      list << validation(attack[0], j, k)
      list << validation(attack[1], j, k)
      list << validation(attack[2], j, k)
    end
  end
  (@mays[0] - attack).each do |i|
    # attack[0..3]が2桁目に含まれている
    (@mays[2] - attack).each do |k|
      next if i == k
      list << validation(i, attack[0], k)
      list << validation(i, attack[1], k)
      list << validation(i, attack[2], k)
    end
    # attack[0..3]が3桁目に含まれている
    (@mays[1] - attack).each do |j|
      next if i == j
      list << validation(i, j, attack[0])
      list << validation(i, j, attack[1])
      list << validation(i, j, attack[2])
    end
  end
  update_possibilities(list)
end

#one_eat_two_bite(attack) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/numeron/calculator.rb', line 186

def one_eat_two_bite(attack)
  # attack以外の可能性がなくなるので、積
  @mays[0] = @mays[0] & attack
  @mays[1] = @mays[1] & attack
  @mays[2] = @mays[2] & attack
  list = [
    validation(attack[0], attack[2], attack[1]),
    validation(attack[2], attack[1], attack[0]),
    validation(attack[1], attack[0], attack[2])
  ].compact
  update_possibilities(list)
end

#one_eat_zero_bite(attack) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/numeron/calculator.rb', line 133

def one_eat_zero_bite(attack)
  list = []
  # 先頭eat
  (@mays[1] - attack).each do |j|
    (@mays[2] - attack).each do |k|
      next if j == k
      list << validation(attack[0], j, k)
    end
  end

  # 真ん中eat
  (@mays[0] - attack).each do |i|
    (@mays[2] - attack).each do |k|
      next if i == k
      list << validation(i, attack[1], k)
    end
  end

  # 末尾eat
  (@mays[0] - attack).each do |i|
    (@mays[1] - attack).each do |j|
      next if i == j
      list << validation(i, j, attack[2])
    end
  end
  update_possibilities(list)
end

#shuffleObject

シャッフル



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/numeron/calculator.rb', line 226

def shuffle
  @mays[0] = @mays[0] | @mays[1] | @mays[2]
  @mays[1] = @mays[0] | @mays[1] | @mays[2]
  @mays[2] = @mays[0] | @mays[1] | @mays[2]
  list = []
  @mays[0].each do |i|
    @mays[1].each do |j|
      next if i == j
      @mays[2].each do |k|
        next if i == k || j == k
        list << validation(i, j, k)
      end
    end
  end
  @possibilities = list.compact
  @histories.each do |history|
    eat_and_bite = history[:eat] + history[:bite]
    if eat_and_bite == 1
      one_eat_or_one_bite(history[:attack])
    elsif eat_and_bite == 2
      two_eat_or_two_bite(history[:attack])
    end
  end
end

#two_eat_or_two_bite(attack) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/numeron/calculator.rb', line 281

def two_eat_or_two_bite(attack)
  list = []
  # 末尾が不明
  (@mays[2] - attack).each do |k|
    list << validation(attack[0], attack[1], k)
    list << validation(attack[0], attack[2], k)
    list << validation(attack[1], attack[0], k)
    list << validation(attack[1], attack[2], k)
    list << validation(attack[2], attack[0], k)
    list << validation(attack[2], attack[1], k)
  end

  # 真ん中が不明
  (@mays[1] - attack).each do |j|
    list << validation(attack[0], j, attack[1])
    list << validation(attack[0], j, attack[2])
    list << validation(attack[1], j, attack[0])
    list << validation(attack[1], j, attack[2])
    list << validation(attack[2], j, attack[0])
    list << validation(attack[2], j, attack[1])
  end

  # 先頭が不明
  (@mays[0] - attack).each do |i|
    list << validation(i, attack[0], attack[1])
    list << validation(i, attack[0], attack[2])
    list << validation(i, attack[1], attack[0])
    list << validation(i, attack[1], attack[2])
    list << validation(i, attack[2], attack[0])
    list << validation(i, attack[2], attack[1])
  end
  update_possibilities(list)
end

#two_eat_zero_bite(attack) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/numeron/calculator.rb', line 199

def two_eat_zero_bite(attack)
  # 先頭2つがeat
  list = []
  (@mays[2] - attack).each do |k|
    list << validation(attack[0], attack[1], k)
  end
  # 先頭、末尾がeat
  (@mays[1] - attack).each do |j|
    list << validation(attack[0], j, attack[2])
  end
  # 真ん中、末尾がeat
  (@mays[0] - attack).each do |i|
    list << validation(i ,attack[1], attack[2])
  end
  update_possibilities(list)
end

#update_possibilities(possibilities) ⇒ Object



315
316
317
318
# File 'lib/numeron/calculator.rb', line 315

def update_possibilities(possibilities)
  possibilities.compact!
  @possibilities = @possibilities.nil? ? possibilities : possibilities & @possibilities
end

#validation(i, j, k) ⇒ Object



216
217
218
219
220
221
222
223
# File 'lib/numeron/calculator.rb', line 216

def validation(i, j, k)
  return nil if i == j || i == k || j == k
  if @mays[0].include?(i) && @mays[1].include?(j) && @mays[2].include?(k)
    return i.to_s + j.to_s + k.to_s
  else
    return nil
  end
end

#zero_eat_one_bite(attack) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/numeron/calculator.rb', line 59

def zero_eat_one_bite(attack)
  # 各桁のeatの可能性がなくなる
  @mays[0] = @mays[0] - [attack[0]]
  @mays[1] = @mays[1] - [attack[1]]
  @mays[2] = @mays[2] - [attack[2]]

  list = []
  (@mays[0] - attack).each do |i|
    (@mays[1] - attack).each do |j|
      next if i == j
      list << validation(i, j, attack[0]) if attack[0] != i || attack[0] != j
      list << validation(i, j, attack[1]) if attack[1] != i || attack[1] != j
    end
  end

  (@mays[0] - attack).each do |i|
    (@mays[2] - attack).each do |k|
      next if i == k
      list << validation(i, attack[0], k) if attack[0] != i || attack[0] != j
      list << validation(i, attack[2], k) if attack[1] != i || attack[1] != j
    end
  end

  (@mays[1] - attack).each do |j|
    (@mays[2] - attack).each do |k|
      next if j == k
      list << validation(attack[1], j, k) if attack[1] != j || attack[1] != k
      list << validation(attack[2], j, k) if attack[2] != j || attack[2] != k
    end
  end
  update_possibilities(list)
end

#zero_eat_three_bite(attack) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/numeron/calculator.rb', line 121

def zero_eat_three_bite(attack)
  # 各桁の可能性が2つに絞られる
  @mays[0] = @mays[0] & [attack[1], attack[2]]
  @mays[1] = @mays[1] & [attack[0], attack[2]]
  @mays[2] = @mays[2] & [attack[0], attack[1]]
  list = [
    validation(attack[1], attack[2], attack[0]),
    validation(attack[2], attack[0], attack[1])
  ].compact
  update_possibilities(list)
end

#zero_eat_two_bite(attack) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/numeron/calculator.rb', line 92

def zero_eat_two_bite(attack)
  @mays[0] = @mays[0] - [attack[0]]
  @mays[1] = @mays[1] - [attack[1]]
  @mays[2] = @mays[2] - [attack[2]]
  list = []

  # 先頭不明
  (@mays[0] - attack).each do |f|
    list << validation(f, attack[0], attack[1])
    list << validation(f, attack[2], attack[0])
    list << validation(f, attack[2], attack[1])
  end

  # 中央不明
  (@mays[1] - attack).each do |f|
    list << validation(attack[1], f, attack[0])
    list << validation(attack[2], f, attack[0])
    list << validation(attack[2], f, attack[1])
  end

  # 末尾不明
  (@mays[2] - attack).each do |f|
    list << validation(attack[1], attack[0], f)
    list << validation(attack[1], attack[2], f)
    list << validation(attack[2], attack[0], f)
  end
  update_possibilities(list)
end

#zero_eat_zero_bite(attack) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/numeron/calculator.rb', line 41

def zero_eat_zero_bite(attack)
  @mays[0] = @mays[0] - attack
  @mays[1] = @mays[1] - attack
  @mays[2] = @mays[2] - attack

  list = []
  @mays[0].each do |i|
    @mays[1].each do |j|
      next if i == j
      @mays[2].each do |k|
        next if i == k || j == k
        list << validation(i, j, k)
      end
    end
  end
  update_possibilities(list)
end