binary_puzzle_solver 0.0.1 → 0.0.2
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/CREDITS.pod +45 -0
- data/README.md +4 -2
- data/binary_puzzle_solver.gemspec +1 -1
- data/lib/binary_puzzle_solver/base.rb +185 -7
- data/lib/binary_puzzle_solver/version.rb +1 -1
- data/test/{parse-board.rb → deduction.rb} +418 -2
- metadata +6 -5
data/CREDITS.pod
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
=encoding utf8
|
2
|
+
|
3
|
+
=head1 The Binary Puzzle Solver credits and thanks file
|
4
|
+
|
5
|
+
=head2 NOTE
|
6
|
+
|
7
|
+
If you believe your name is missing here, please contact me at
|
8
|
+
L<http://www.shlomifish.org/me/contact-me/>.
|
9
|
+
|
10
|
+
=head2 List of Credits.
|
11
|
+
|
12
|
+
=over 4
|
13
|
+
|
14
|
+
=item * Shlomi Fish
|
15
|
+
|
16
|
+
Doing the bulk of the work on the solver.
|
17
|
+
|
18
|
+
=item * Meir Maor
|
19
|
+
|
20
|
+
Giving a talk about the Scala programming language on August Penguin 2012,
|
21
|
+
which prompted work on the solver.
|
22
|
+
|
23
|
+
=item * Richard Klement (tybalt89)
|
24
|
+
|
25
|
+
Writing an alternative solver in hacky perl and releasing it as open-source
|
26
|
+
software under the MIT/X11 license.
|
27
|
+
|
28
|
+
=item * Steve Klabnik
|
29
|
+
|
30
|
+
Writing a
|
31
|
+
L<tutorial for making ruby Gems|http://timelessrepo.com/making-ruby-gems> which
|
32
|
+
proved to be useful. Also answered some questions on IRC
|
33
|
+
|
34
|
+
=item * judyfor from #ruby-lang on Freenode
|
35
|
+
|
36
|
+
Answering some questions, and recommending an rspec rakefile integration
|
37
|
+
snippet.
|
38
|
+
|
39
|
+
=item * Kizano_werk from #perl on Freenode
|
40
|
+
|
41
|
+
Helping me diagnose a rubygems.org HTTP problem that prevented me from
|
42
|
+
uploading this gem (and other gems in the future).
|
43
|
+
|
44
|
+
=back 4
|
45
|
+
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# Binary\_Puzzle\_Solver
|
2
2
|
|
3
|
-
|
3
|
+
This gem provides an API for solving the Binary Puzzles from
|
4
|
+
[BinaryPuzzle.com](http://www.binarypuzzle.com/) . In the future
|
5
|
+
it will also provide a command-line interface.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.authors = ["Shlomi Fish"]
|
11
11
|
s.email = ["shlomif@cpan.org"]
|
12
12
|
# TODO : add a better home page on http://www.shlomifish.org/ .
|
13
|
-
s.homepage = "http://
|
13
|
+
s.homepage = "http://www.shlomifish.org/open-source/projects/japanese-puzzle-games/binary-puzzle/"
|
14
14
|
s.summary = %q{A solver for http://www.binarypuzzle.com/ instances}
|
15
15
|
s.description = %q{This is a solver for instances of the so-called Binary
|
16
16
|
Puzzle from http://www.binarypuzzle.com/ . It is incomplete, but
|
@@ -481,8 +481,9 @@ module Binary_Puzzle_Solver
|
|
481
481
|
return
|
482
482
|
}
|
483
483
|
|
484
|
-
row.
|
485
|
-
|
484
|
+
row.iter_of_handles().each do |h|
|
485
|
+
x = h.x
|
486
|
+
cell_state = h.get_cell.state
|
486
487
|
|
487
488
|
if cell_state == Cell::UNKNOWN
|
488
489
|
handle_prev_cell_states.call(x)
|
@@ -542,7 +543,10 @@ module Binary_Puzzle_Solver
|
|
542
543
|
if (full_val)
|
543
544
|
opposite_val = opposite_value(full_val)
|
544
545
|
|
545
|
-
row.
|
546
|
+
row.iter_of_handles().each do |cell_h|
|
547
|
+
x = cell_h.x
|
548
|
+
cell = cell_h.get_cell
|
549
|
+
|
546
550
|
cell_state = cell.state
|
547
551
|
|
548
552
|
if cell_state == Cell::UNKNOWN
|
@@ -559,6 +563,131 @@ module Binary_Puzzle_Solver
|
|
559
563
|
return
|
560
564
|
end
|
561
565
|
|
566
|
+
def check_exceeded_numbers_while_accounting_for_two_unknown_gaps(params)
|
567
|
+
row_idx = params[:idx]
|
568
|
+
|
569
|
+
row = get_row_handle(row_idx)
|
570
|
+
|
571
|
+
gaps = {}
|
572
|
+
|
573
|
+
next_gap = []
|
574
|
+
|
575
|
+
add_gap = lambda {
|
576
|
+
l = next_gap.length
|
577
|
+
if (l > 0)
|
578
|
+
if not gaps[l]
|
579
|
+
gaps[l] = []
|
580
|
+
end
|
581
|
+
gaps[l] << next_gap
|
582
|
+
next_gap = []
|
583
|
+
end
|
584
|
+
}
|
585
|
+
|
586
|
+
row.iter_of_handles().each do |cell_h|
|
587
|
+
if (cell_h.get_state == Cell::UNKNOWN)
|
588
|
+
next_gap << cell_h.x
|
589
|
+
else
|
590
|
+
add_gap.call()
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
add_gap.call()
|
595
|
+
|
596
|
+
if (gaps.has_key?(2)) then
|
597
|
+
implicit_counts = {Cell::ZERO => 0, Cell::ONE => 0,}
|
598
|
+
gaps[2].each do |gap|
|
599
|
+
x_s = []
|
600
|
+
if (gap[0] > 0)
|
601
|
+
x_s << gap[0]-1
|
602
|
+
end
|
603
|
+
if (gap[-1] < row.max_idx)
|
604
|
+
x_s << gap[-1]+1
|
605
|
+
end
|
606
|
+
|
607
|
+
bordering_values = {Cell::ZERO => 0, Cell::ONE => 0,}
|
608
|
+
x_s.each do |x|
|
609
|
+
bordering_values[row.get_state(x)] += 1
|
610
|
+
end
|
611
|
+
|
612
|
+
for v in [Cell::ZERO, Cell::ONE] do
|
613
|
+
if bordering_values[opposite_value(v)] > 0
|
614
|
+
implicit_counts[v] += 1
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
summ = row.get_summary()
|
620
|
+
|
621
|
+
v = [Cell::ZERO, Cell::ONE].find {
|
622
|
+
|v| summ.get_count(v) + implicit_counts[v] \
|
623
|
+
== summ.half_limit()
|
624
|
+
}
|
625
|
+
|
626
|
+
if v then
|
627
|
+
gap_keys = gaps.keys.select { |x| x != 2 }
|
628
|
+
opposite_val = opposite_value(v)
|
629
|
+
gap_keys.each do |k|
|
630
|
+
gaps[k].each do |gap|
|
631
|
+
gap.each do |x|
|
632
|
+
perform_and_append_move(
|
633
|
+
:coord => row.get_coord(x),
|
634
|
+
:val => opposite_val,
|
635
|
+
:reason => \
|
636
|
+
"Analysis of gaps and their neighboring values",
|
637
|
+
:dir => row.col_dim()
|
638
|
+
)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
def check_try_placing_last_of_certain_digit_in_row(params)
|
647
|
+
row_idx = params[:idx]
|
648
|
+
|
649
|
+
row = get_row_handle(row_idx)
|
650
|
+
|
651
|
+
summary = row.get_summary()
|
652
|
+
|
653
|
+
v = [Cell::ZERO, Cell::ONE].find {
|
654
|
+
|v| summary.get_count(v) == summary.half_limit() - 1
|
655
|
+
}
|
656
|
+
|
657
|
+
if not(v) then
|
658
|
+
return
|
659
|
+
end
|
660
|
+
|
661
|
+
oppose_v = opposite_value(v)
|
662
|
+
|
663
|
+
values = row.iter_of_states().to_a
|
664
|
+
coords = row.where_values_are(Cell::UNKNOWN)
|
665
|
+
|
666
|
+
coords_copy = Array.new(coords)
|
667
|
+
|
668
|
+
for x in coords do
|
669
|
+
v_s = Array.new(values)
|
670
|
+
for x_to_fill in coords_copy do
|
671
|
+
v_s[x_to_fill] = ((x_to_fill == x) ? v : oppose_v)
|
672
|
+
end
|
673
|
+
|
674
|
+
# Is there a three in a row?
|
675
|
+
if ((0 .. (v_s.length - 3)).to_a.index { |i|
|
676
|
+
(1 .. 2).all? { |offset| v_s[i] == v_s[i+offset] }
|
677
|
+
}) then
|
678
|
+
perform_and_append_move(
|
679
|
+
:coord => row.get_coord(x),
|
680
|
+
:val => oppose_v,
|
681
|
+
:reason => "Trying opposite value that is the last remaining results in three-in-a-row",
|
682
|
+
:dir => col_dim()
|
683
|
+
)
|
684
|
+
return
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
return
|
689
|
+
end
|
690
|
+
|
562
691
|
def validate_rows()
|
563
692
|
# TODO
|
564
693
|
complete_rows_map = Hash.new
|
@@ -587,7 +716,7 @@ module Binary_Puzzle_Solver
|
|
587
716
|
end
|
588
717
|
|
589
718
|
def get_string()
|
590
|
-
return
|
719
|
+
return iter_of_handles().map { |cell_h| cell_h.get_char() }.join('')
|
591
720
|
end
|
592
721
|
|
593
722
|
def col_dim()
|
@@ -610,12 +739,33 @@ module Binary_Puzzle_Solver
|
|
610
739
|
return view.get_cell_state(get_coord(x))
|
611
740
|
end
|
612
741
|
|
742
|
+
def get_cell(x)
|
743
|
+
return view._get_cell(get_coord(x))
|
744
|
+
end
|
745
|
+
|
613
746
|
def iter
|
614
747
|
return view.dim_range(col_dim()).map { |x|
|
615
|
-
[x,
|
748
|
+
[x, get_cell(x)]
|
616
749
|
}
|
617
750
|
end
|
618
751
|
|
752
|
+
def get_cell_handle(x)
|
753
|
+
return CellHandle.new(self, x)
|
754
|
+
end
|
755
|
+
|
756
|
+
def iter_of_handles
|
757
|
+
return view.dim_range(col_dim()).map { |x| get_cell_handle(x) }
|
758
|
+
end
|
759
|
+
|
760
|
+
def iter_of_states
|
761
|
+
return iter_of_handles.map { |x| x.get_state() }
|
762
|
+
end
|
763
|
+
|
764
|
+
def where_values_are(v)
|
765
|
+
return iter_of_handles.select { |x|
|
766
|
+
x.get_state() == v }.map { |h| h.x }
|
767
|
+
end
|
768
|
+
|
619
769
|
def check_for_duplicated(complete_rows_map)
|
620
770
|
summary = get_summary()
|
621
771
|
|
@@ -652,8 +802,8 @@ module Binary_Puzzle_Solver
|
|
652
802
|
end
|
653
803
|
}
|
654
804
|
|
655
|
-
|
656
|
-
cell_state =
|
805
|
+
iter_of_handles().each do |cell_h|
|
806
|
+
cell_state = cell_h.get_state
|
657
807
|
if cell_state == prev_cell_state then
|
658
808
|
count += 1
|
659
809
|
else
|
@@ -677,6 +827,34 @@ module Binary_Puzzle_Solver
|
|
677
827
|
end
|
678
828
|
end
|
679
829
|
|
830
|
+
class CellHandle
|
831
|
+
|
832
|
+
attr_reader :row_handle, :x
|
833
|
+
|
834
|
+
def initialize (row_handle, x)
|
835
|
+
@row_handle = row_handle
|
836
|
+
@x = x
|
837
|
+
|
838
|
+
return
|
839
|
+
end
|
840
|
+
|
841
|
+
def get_coord()
|
842
|
+
return row_handle.get_coord(x)
|
843
|
+
end
|
844
|
+
|
845
|
+
def get_state()
|
846
|
+
return row_handle.get_state(x)
|
847
|
+
end
|
848
|
+
|
849
|
+
def get_cell()
|
850
|
+
return row_handle.get_cell(x)
|
851
|
+
end
|
852
|
+
|
853
|
+
def get_char()
|
854
|
+
return get_cell().get_char()
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
680
858
|
def Binary_Puzzle_Solver.gen_board_from_string_v1(string)
|
681
859
|
lines = string.lines.map { |l| l.chomp }
|
682
860
|
line_lens = lines.map { |l| l.length }
|
@@ -53,8 +53,8 @@ def compare_boards(got, expected)
|
|
53
53
|
got.get_cell_state(coord).should == expected.get_cell_state(coord)
|
54
54
|
rescue
|
55
55
|
puts "Wrong coord in x=#{x} y=#{y}"
|
56
|
-
puts "Got
|
57
|
-
puts "Expected
|
56
|
+
puts "Got ==\n#{got.as_string()}\n"
|
57
|
+
puts "Expected ==\n#{expected.as_string()}\n"
|
58
58
|
raise
|
59
59
|
end
|
60
60
|
end
|
@@ -215,6 +215,235 @@ EOF
|
|
215
215
|
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
216
216
|
end
|
217
217
|
|
218
|
+
def get_6x6_hard_board_1__initial()
|
219
|
+
input_str = <<'EOF'
|
220
|
+
| 1 |
|
221
|
+
| 0 1|
|
222
|
+
|0 0 |
|
223
|
+
| 11 |
|
224
|
+
| |
|
225
|
+
|1 0 |
|
226
|
+
EOF
|
227
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
228
|
+
end
|
229
|
+
|
230
|
+
def get_6x6_hard_board_1__intermediate()
|
231
|
+
input_str = <<'EOF'
|
232
|
+
|0 1 |
|
233
|
+
|1 0 1|
|
234
|
+
|0 0 |
|
235
|
+
|0110 |
|
236
|
+
|1 |
|
237
|
+
|1 0 |
|
238
|
+
EOF
|
239
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
240
|
+
end
|
241
|
+
|
242
|
+
def get_6x6_hard_board_1__final()
|
243
|
+
input_str = <<'EOF'
|
244
|
+
|010110|
|
245
|
+
|100101|
|
246
|
+
|011001|
|
247
|
+
|011010|
|
248
|
+
|100110|
|
249
|
+
|101001|
|
250
|
+
EOF
|
251
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
252
|
+
end
|
253
|
+
|
254
|
+
def get_6x6_hard_board_2__initial()
|
255
|
+
input_str = <<'EOF'
|
256
|
+
| 11 1|
|
257
|
+
|00 |
|
258
|
+
| |
|
259
|
+
| 1 0|
|
260
|
+
| |
|
261
|
+
| 0 |
|
262
|
+
EOF
|
263
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
264
|
+
end
|
265
|
+
|
266
|
+
def get_6x6_hard_board_2__intermediate()
|
267
|
+
input_str = <<'EOF'
|
268
|
+
|011001|
|
269
|
+
|001 |
|
270
|
+
|1 0 |
|
271
|
+
| 1 0|
|
272
|
+
| 0 |
|
273
|
+
| 1001 |
|
274
|
+
EOF
|
275
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
276
|
+
end
|
277
|
+
|
278
|
+
def get_6x6_hard_board_2__intermediate_2()
|
279
|
+
input_str = <<'EOF'
|
280
|
+
|011001|
|
281
|
+
|001101|
|
282
|
+
|100110|
|
283
|
+
|011010|
|
284
|
+
|100101|
|
285
|
+
|110010|
|
286
|
+
EOF
|
287
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
288
|
+
end
|
289
|
+
|
290
|
+
def get_6x6_hard_board_3__initial()
|
291
|
+
input_str = <<'EOF'
|
292
|
+
|1 0 0|
|
293
|
+
| |
|
294
|
+
| 11 |
|
295
|
+
| 1 1 |
|
296
|
+
| 0|
|
297
|
+
| 01 |
|
298
|
+
EOF
|
299
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
300
|
+
end
|
301
|
+
|
302
|
+
def get_6x6_hard_board_3__intermediate()
|
303
|
+
input_str = <<'EOF'
|
304
|
+
|100110|
|
305
|
+
|101001|
|
306
|
+
|011001|
|
307
|
+
|010110|
|
308
|
+
|101010|
|
309
|
+
|010101|
|
310
|
+
EOF
|
311
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
312
|
+
end
|
313
|
+
|
314
|
+
def get_10x10_easy_board_1__initial()
|
315
|
+
input_str = <<'EOF'
|
316
|
+
| 1 |
|
317
|
+
| 00 0 1 |
|
318
|
+
| 0 1 0 0|
|
319
|
+
| 1 1 |
|
320
|
+
|1 1 1|
|
321
|
+
| 1 |
|
322
|
+
| 0 1 0 |
|
323
|
+
| 11 0|
|
324
|
+
| 0 0 1 0|
|
325
|
+
|0 0 1 |
|
326
|
+
EOF
|
327
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
328
|
+
end
|
329
|
+
|
330
|
+
def get_10x10_easy_board_1__final()
|
331
|
+
input_str = <<'EOF'
|
332
|
+
|0110010101|
|
333
|
+
|1001100110|
|
334
|
+
|1001101010|
|
335
|
+
|0110011001|
|
336
|
+
|1010100101|
|
337
|
+
|0101010110|
|
338
|
+
|1001101001|
|
339
|
+
|0110110100|
|
340
|
+
|1010011010|
|
341
|
+
|0101001011|
|
342
|
+
EOF
|
343
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
def get_10x10_hard_board_1__initial()
|
348
|
+
input_str = <<'EOF'
|
349
|
+
| 0 |
|
350
|
+
|0 0 1 |
|
351
|
+
| 1 |
|
352
|
+
| 0 0|
|
353
|
+
|1 00 1 |
|
354
|
+
| |
|
355
|
+
| 0 1 1 |
|
356
|
+
|1 11|
|
357
|
+
| 0 |
|
358
|
+
|1 1 1 1 |
|
359
|
+
EOF
|
360
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
361
|
+
end
|
362
|
+
|
363
|
+
def get_10x10_hard_board_1__final()
|
364
|
+
input_str = <<'EOF'
|
365
|
+
|1101100100|
|
366
|
+
|0101011001|
|
367
|
+
|0010101011|
|
368
|
+
|1011010100|
|
369
|
+
|1100110010|
|
370
|
+
|0011001101|
|
371
|
+
|0100110110|
|
372
|
+
|1001001011|
|
373
|
+
|0110010101|
|
374
|
+
|1010101010|
|
375
|
+
EOF
|
376
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
377
|
+
end
|
378
|
+
|
379
|
+
def get_10x10_hard_board_2__initial()
|
380
|
+
input_str = <<'EOF'
|
381
|
+
| 0 1 0|
|
382
|
+
| 1 1 0 |
|
383
|
+
| 0 10 |
|
384
|
+
| 0 |
|
385
|
+
| 0 |
|
386
|
+
| 1 0|
|
387
|
+
| 1 0 |
|
388
|
+
| 0 0 |
|
389
|
+
| 00 0 0|
|
390
|
+
| 0 1 0 |
|
391
|
+
EOF
|
392
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
393
|
+
end
|
394
|
+
|
395
|
+
def get_10x10_hard_board_2__final()
|
396
|
+
input_str = <<'EOF'
|
397
|
+
|0110011010|
|
398
|
+
|0110100101|
|
399
|
+
|1001010101|
|
400
|
+
|1001101010|
|
401
|
+
|0110010101|
|
402
|
+
|1011001010|
|
403
|
+
|0101100110|
|
404
|
+
|0010110101|
|
405
|
+
|1001011010|
|
406
|
+
|1100101001|
|
407
|
+
EOF
|
408
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
409
|
+
end
|
410
|
+
|
411
|
+
def get_12x12_hard_board_1__initial()
|
412
|
+
input_str = <<'EOF'
|
413
|
+
| 1 1 0|
|
414
|
+
| 0 1 1 |
|
415
|
+
| 1 0 0 0|
|
416
|
+
|00 1 |
|
417
|
+
| 00 0 |
|
418
|
+
| 0 0 1 |
|
419
|
+
| 00 0 0|
|
420
|
+
| 00 1 |
|
421
|
+
| 0 1 |
|
422
|
+
|00 0 |
|
423
|
+
| 00 |
|
424
|
+
|00 0 |
|
425
|
+
EOF
|
426
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
427
|
+
end
|
428
|
+
|
429
|
+
def get_12x12_hard_board_1__final()
|
430
|
+
input_str = <<'EOF'
|
431
|
+
|011010101100|
|
432
|
+
|010100110011|
|
433
|
+
|101101010010|
|
434
|
+
|001011001101|
|
435
|
+
|110100110010|
|
436
|
+
|100100101101|
|
437
|
+
|011011001010|
|
438
|
+
|100101010101|
|
439
|
+
|110010110100|
|
440
|
+
|001011001011|
|
441
|
+
|110101100100|
|
442
|
+
|001010011011|
|
443
|
+
EOF
|
444
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
445
|
+
end
|
446
|
+
|
218
447
|
describe "construct_board" do
|
219
448
|
it "6*6 Easy board No. 1 should" do
|
220
449
|
|
@@ -579,4 +808,191 @@ describe "rudimentary_deduction" do
|
|
579
808
|
# binding.pry
|
580
809
|
compare_boards(board, final_board)
|
581
810
|
end
|
811
|
+
|
812
|
+
it "Solving 6*6 Hard board No. 1 should" do
|
813
|
+
|
814
|
+
board = get_6x6_hard_board_1__initial()
|
815
|
+
|
816
|
+
board.add_to_iters_quota(1_000_000_000);
|
817
|
+
|
818
|
+
board.try_to_solve_using(
|
819
|
+
:methods => [
|
820
|
+
:check_and_handle_sequences_in_row,
|
821
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
822
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
823
|
+
]
|
824
|
+
);
|
825
|
+
|
826
|
+
intermediate_board = get_6x6_hard_board_1__intermediate();
|
827
|
+
|
828
|
+
# binding.pry
|
829
|
+
compare_boards(board, intermediate_board)
|
830
|
+
|
831
|
+
board.try_to_solve_using(
|
832
|
+
:methods => [
|
833
|
+
:check_and_handle_sequences_in_row,
|
834
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
835
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
836
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
837
|
+
]
|
838
|
+
);
|
839
|
+
|
840
|
+
intermediate_board_2 = get_6x6_hard_board_1__final();
|
841
|
+
|
842
|
+
# binding.pry
|
843
|
+
compare_boards(board, intermediate_board_2)
|
844
|
+
end
|
845
|
+
|
846
|
+
it "Solving 6*6 Hard board No. 2 should" do
|
847
|
+
|
848
|
+
board = get_6x6_hard_board_2__initial()
|
849
|
+
|
850
|
+
board.add_to_iters_quota(1_000_000_000);
|
851
|
+
|
852
|
+
board.try_to_solve_using(
|
853
|
+
:methods => [
|
854
|
+
:check_and_handle_sequences_in_row,
|
855
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
856
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
857
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
858
|
+
]
|
859
|
+
);
|
860
|
+
|
861
|
+
intermediate_board = get_6x6_hard_board_2__intermediate();
|
862
|
+
|
863
|
+
# binding.pry
|
864
|
+
compare_boards(board, intermediate_board)
|
865
|
+
|
866
|
+
board.try_to_solve_using(
|
867
|
+
:methods => [
|
868
|
+
:check_and_handle_sequences_in_row,
|
869
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
870
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
871
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
872
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
873
|
+
]
|
874
|
+
)
|
875
|
+
|
876
|
+
final_board = get_6x6_hard_board_2__intermediate_2();
|
877
|
+
|
878
|
+
# binding.pry
|
879
|
+
compare_boards(board, final_board)
|
880
|
+
end
|
881
|
+
|
882
|
+
it "Solving 6*6 Hard board No. 3 should" do
|
883
|
+
|
884
|
+
board = get_6x6_hard_board_3__initial()
|
885
|
+
|
886
|
+
board.add_to_iters_quota(1_000_000_000);
|
887
|
+
|
888
|
+
# binding.pry
|
889
|
+
board.try_to_solve_using(
|
890
|
+
:methods => [
|
891
|
+
:check_and_handle_sequences_in_row,
|
892
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
893
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
894
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
895
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
896
|
+
]
|
897
|
+
)
|
898
|
+
|
899
|
+
intermediate_board = get_6x6_hard_board_3__intermediate()
|
900
|
+
# binding.pry
|
901
|
+
|
902
|
+
compare_boards(board, intermediate_board)
|
903
|
+
end
|
904
|
+
|
905
|
+
it "Solving 10*10 Easy board No. 1 should" do
|
906
|
+
|
907
|
+
board = get_10x10_easy_board_1__initial()
|
908
|
+
|
909
|
+
board.add_to_iters_quota(1_000_000_000);
|
910
|
+
|
911
|
+
board.try_to_solve_using(
|
912
|
+
:methods => [
|
913
|
+
:check_and_handle_sequences_in_row,
|
914
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
915
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
916
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
917
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
918
|
+
]
|
919
|
+
);
|
920
|
+
|
921
|
+
final_board = get_10x10_easy_board_1__final()
|
922
|
+
|
923
|
+
compare_boards(board, final_board)
|
924
|
+
end
|
925
|
+
|
926
|
+
it "Solving 10*10 Hard board No. 1 should" do
|
927
|
+
|
928
|
+
board = get_10x10_hard_board_1__initial()
|
929
|
+
|
930
|
+
board.add_to_iters_quota(1_000_000_000);
|
931
|
+
|
932
|
+
board.try_to_solve_using(
|
933
|
+
:methods => [
|
934
|
+
:check_and_handle_sequences_in_row,
|
935
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
936
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
937
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
938
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
939
|
+
]
|
940
|
+
);
|
941
|
+
|
942
|
+
board.get_cell_state(
|
943
|
+
Binary_Puzzle_Solver::Coord.new(:x => 9, :y => 1)
|
944
|
+
).should == ONE
|
945
|
+
|
946
|
+
final_board = get_10x10_hard_board_1__final()
|
947
|
+
|
948
|
+
# binding.pry
|
949
|
+
|
950
|
+
compare_boards(board, final_board)
|
951
|
+
end
|
952
|
+
|
953
|
+
it "Solving 10*10 Hard board No. 2 should" do
|
954
|
+
|
955
|
+
board = get_10x10_hard_board_2__initial()
|
956
|
+
|
957
|
+
board.add_to_iters_quota(1_000_000_000);
|
958
|
+
|
959
|
+
board.try_to_solve_using(
|
960
|
+
:methods => [
|
961
|
+
:check_and_handle_sequences_in_row,
|
962
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
963
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
964
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
965
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
966
|
+
]
|
967
|
+
);
|
968
|
+
|
969
|
+
final_board = get_10x10_hard_board_2__final()
|
970
|
+
|
971
|
+
# binding.pry
|
972
|
+
|
973
|
+
compare_boards(board, final_board)
|
974
|
+
end
|
975
|
+
|
976
|
+
it "Solving 12*12 Hard board No. 1 should" do
|
977
|
+
|
978
|
+
board = get_12x12_hard_board_1__initial()
|
979
|
+
|
980
|
+
board.add_to_iters_quota(1_000_000_000);
|
981
|
+
|
982
|
+
board.try_to_solve_using(
|
983
|
+
:methods => [
|
984
|
+
:check_and_handle_sequences_in_row,
|
985
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
986
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
987
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
988
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
989
|
+
]
|
990
|
+
);
|
991
|
+
|
992
|
+
final_board = get_12x12_hard_board_1__final()
|
993
|
+
|
994
|
+
# binding.pry
|
995
|
+
|
996
|
+
compare_boards(board, final_board)
|
997
|
+
end
|
582
998
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: binary_puzzle_solver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: launchy
|
@@ -52,6 +52,7 @@ executables: []
|
|
52
52
|
extensions: []
|
53
53
|
extra_rdoc_files: []
|
54
54
|
files:
|
55
|
+
- CREDITS.pod
|
55
56
|
- Gemfile
|
56
57
|
- LICENSE.txt
|
57
58
|
- Makefile
|
@@ -61,8 +62,8 @@ files:
|
|
61
62
|
- lib/binary_puzzle_solver.rb
|
62
63
|
- lib/binary_puzzle_solver/base.rb
|
63
64
|
- lib/binary_puzzle_solver/version.rb
|
64
|
-
- test/
|
65
|
-
homepage: http://
|
65
|
+
- test/deduction.rb
|
66
|
+
homepage: http://www.shlomifish.org/open-source/projects/japanese-puzzle-games/binary-puzzle/
|
66
67
|
licenses: []
|
67
68
|
post_install_message:
|
68
69
|
rdoc_options: []
|
@@ -87,4 +88,4 @@ signing_key:
|
|
87
88
|
specification_version: 3
|
88
89
|
summary: A solver for http://www.binarypuzzle.com/ instances
|
89
90
|
test_files:
|
90
|
-
- test/
|
91
|
+
- test/deduction.rb
|