binary_puzzle_solver 0.0.3 → 0.0.4
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/bin/binary-puzzle-solve +5 -0
- data/lib/binary_puzzle_solver/base.rb +128 -38
- data/lib/binary_puzzle_solver/version.rb +1 -1
- data/test/data/boards/12x12_hard_no_1.binpuz.board +12 -0
- data/test/data/boards/2013-06-07-12x12_very_hard.binpuz.board +12 -0
- data/test/deduction.rb +189 -0
- metadata +6 -2
data/bin/binary-puzzle-solve
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
require 'binary_puzzle_solver'
|
4
4
|
|
5
5
|
filename = ARGV.shift
|
6
|
+
if (not filename)
|
7
|
+
raise "Missing path to the file containing a layout."
|
8
|
+
end
|
9
|
+
|
6
10
|
board = Binary_Puzzle_Solver.gen_board_from_string_v1(IO.read(filename))
|
7
11
|
|
8
12
|
board.add_to_iters_quota(1_000_000_000);
|
@@ -13,6 +17,7 @@ board.try_to_solve_using(
|
|
13
17
|
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
14
18
|
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
15
19
|
:check_try_placing_last_of_certain_digit_in_row,
|
20
|
+
:check_try_placing_last_of_certain_digit_in_row_to_avoid_dups,
|
16
21
|
]
|
17
22
|
);
|
18
23
|
|
@@ -80,15 +80,19 @@ module Binary_Puzzle_Solver
|
|
80
80
|
return
|
81
81
|
end
|
82
82
|
|
83
|
-
def
|
84
|
-
if
|
83
|
+
def self.get_state_char(val)
|
84
|
+
if val == ZERO
|
85
85
|
return '0'
|
86
|
-
elsif
|
86
|
+
elsif val == ONE
|
87
87
|
return '1'
|
88
88
|
else
|
89
|
-
raise RuntimeError, "
|
89
|
+
raise RuntimeError, "get_state_char() called on Unset state"
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
def get_char()
|
94
|
+
return Cell.get_state_char(state)
|
95
|
+
end
|
92
96
|
end
|
93
97
|
|
94
98
|
# A summary for a row or column.
|
@@ -165,6 +169,7 @@ module Binary_Puzzle_Solver
|
|
165
169
|
class Board
|
166
170
|
|
167
171
|
attr_reader :iters_quota, :num_iters_done
|
172
|
+
|
168
173
|
def initialize (params)
|
169
174
|
@dim_limits = {:x => params[:x], :y => params[:y]}
|
170
175
|
@cells = dim_range(:y).map {
|
@@ -174,6 +179,10 @@ module Binary_Puzzle_Solver
|
|
174
179
|
:x => dim_range(:x).map { RowSummary.new(limit(:y)); },
|
175
180
|
:y => dim_range(:y).map { RowSummary.new(limit(:x)); }
|
176
181
|
}
|
182
|
+
@complete_rows_map = {
|
183
|
+
:x => Hash.new,
|
184
|
+
:y => Hash.new
|
185
|
+
}
|
177
186
|
@old_moves = []
|
178
187
|
@new_moves = []
|
179
188
|
|
@@ -258,10 +267,37 @@ module Binary_Puzzle_Solver
|
|
258
267
|
return @cells[y][x]
|
259
268
|
end
|
260
269
|
|
270
|
+
def list_views
|
271
|
+
return [false, true].map { |v| get_view(:rotate => v) }
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_complete_map(dir)
|
275
|
+
return @complete_rows_map[dir]
|
276
|
+
end
|
277
|
+
|
261
278
|
def set_cell_state(coord, state)
|
262
279
|
_get_cell(coord).set_state(state)
|
263
|
-
|
264
|
-
|
280
|
+
|
281
|
+
mymap = @complete_rows_map
|
282
|
+
list_views().each do |v|
|
283
|
+
row_dim = v.row_dim()
|
284
|
+
real_row_dim = v.mapped_row_dim()
|
285
|
+
row_idx = coord.method(real_row_dim).call()
|
286
|
+
summary = v.get_row_summary(:dim => row_dim, :idx => row_idx)
|
287
|
+
|
288
|
+
# puts "Coord = (x=#{coord.x},y=#{coord.y}) row_dim = #{row_dim} RowIdx = #{row_idx} mapped_row_dim = #{v.mapped_row_dim}"
|
289
|
+
summary.inc_count(state)
|
290
|
+
|
291
|
+
if summary.are_both_full() then
|
292
|
+
str = v.get_row_handle(row_idx).get_string()
|
293
|
+
mymap[real_row_dim][str] ||= []
|
294
|
+
arr = mymap[real_row_dim][str]
|
295
|
+
arr << row_idx
|
296
|
+
if (arr.length > 1) then
|
297
|
+
raise GameIntegrityException, "Duplicate rows at dim #{row_dim} #{arr.join(',')}"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
265
301
|
return
|
266
302
|
end
|
267
303
|
|
@@ -300,7 +336,7 @@ module Binary_Puzzle_Solver
|
|
300
336
|
|
301
337
|
def try_to_solve_using (params)
|
302
338
|
methods_list = params[:methods]
|
303
|
-
views =
|
339
|
+
views = list_views()
|
304
340
|
|
305
341
|
catch :out_of_iters do
|
306
342
|
first_iter = true
|
@@ -349,11 +385,9 @@ module Binary_Puzzle_Solver
|
|
349
385
|
end
|
350
386
|
|
351
387
|
def validate()
|
352
|
-
views = [get_view(:rotate => false), get_view(:rotate => true), ]
|
353
|
-
|
354
388
|
is_final = true
|
355
389
|
|
356
|
-
|
390
|
+
list_views().each do |v|
|
357
391
|
view_final = v.validate_rows()
|
358
392
|
is_final &&= view_final
|
359
393
|
end
|
@@ -423,6 +457,14 @@ module Binary_Puzzle_Solver
|
|
423
457
|
return :x
|
424
458
|
end
|
425
459
|
|
460
|
+
def mapped_row_dim()
|
461
|
+
return _calc_mapped_dir(row_dim())
|
462
|
+
end
|
463
|
+
|
464
|
+
def get_complete_row_map()
|
465
|
+
return @board.get_complete_map(mapped_row_dim())
|
466
|
+
end
|
467
|
+
|
426
468
|
def get_row_handle(idx)
|
427
469
|
return RowHandle.new(self, idx)
|
428
470
|
end
|
@@ -444,8 +486,14 @@ module Binary_Puzzle_Solver
|
|
444
486
|
return
|
445
487
|
end
|
446
488
|
|
489
|
+
def set_cell_state(coord, state)
|
490
|
+
@board.set_cell_state(
|
491
|
+
_calc_mapped_coord(coord), state
|
492
|
+
)
|
493
|
+
end
|
494
|
+
|
447
495
|
def perform_and_append_move(params)
|
448
|
-
set_cell_state(params[:coord], params[:val])
|
496
|
+
set_cell_state( params[:coord], params[:val] )
|
449
497
|
_append_move(params)
|
450
498
|
end
|
451
499
|
|
@@ -647,9 +695,55 @@ module Binary_Puzzle_Solver
|
|
647
695
|
end
|
648
696
|
end
|
649
697
|
|
698
|
+
def _do_values_have_a_three_in_a_row(params)
|
699
|
+
row_idx = params[:idx]
|
700
|
+
v_s = params[:v_s]
|
701
|
+
|
702
|
+
return {
|
703
|
+
:verdict => ((0 .. (v_s.length - 3)).to_a.index { |i|
|
704
|
+
(1 .. 2).all? { |offset| v_s[i] == v_s[i+offset] }
|
705
|
+
}),
|
706
|
+
:reason => "Trying opposite value that is the last remaining results in three-in-a-row",
|
707
|
+
}
|
708
|
+
end
|
709
|
+
|
710
|
+
def _are_values_duplicates(params)
|
711
|
+
row_idx = params[:idx]
|
712
|
+
v_s = params[:v_s]
|
713
|
+
|
714
|
+
str = RowHandle.calc_iter_of_states_str(v_s)
|
715
|
+
mymap = get_complete_row_map()
|
716
|
+
|
717
|
+
verdict = (mymap.has_key?(str) and (mymap[str].length > 0));
|
718
|
+
|
719
|
+
return {
|
720
|
+
:verdict => verdict,
|
721
|
+
:reason => "Trying opposite value that is the last remaining results in a duplicate row",
|
722
|
+
}
|
723
|
+
end
|
724
|
+
|
725
|
+
def check_try_placing_last_of_certain_digit_in_row_to_avoid_dups(params)
|
726
|
+
row_idx = params[:idx]
|
727
|
+
|
728
|
+
return _generic_check_try_placing_last_digit(
|
729
|
+
:idx => row_idx,
|
730
|
+
:callback_method => :_are_values_duplicates,
|
731
|
+
)
|
732
|
+
end
|
733
|
+
|
650
734
|
def check_try_placing_last_of_certain_digit_in_row(params)
|
651
735
|
row_idx = params[:idx]
|
652
736
|
|
737
|
+
return _generic_check_try_placing_last_digit(
|
738
|
+
:idx => row_idx,
|
739
|
+
:callback_method => :_do_values_have_a_three_in_a_row,
|
740
|
+
)
|
741
|
+
end
|
742
|
+
|
743
|
+
def _generic_check_try_placing_last_digit(params)
|
744
|
+
row_idx = params[:idx]
|
745
|
+
callback_method = params[:callback_method]
|
746
|
+
|
653
747
|
row = get_row_handle(row_idx)
|
654
748
|
|
655
749
|
summary = row.get_summary()
|
@@ -676,16 +770,18 @@ module Binary_Puzzle_Solver
|
|
676
770
|
end
|
677
771
|
|
678
772
|
# Is there a three in a row?
|
679
|
-
|
680
|
-
|
681
|
-
}) then
|
682
|
-
perform_and_append_move(
|
683
|
-
:coord => row.get_coord(x),
|
684
|
-
:val => oppose_v,
|
685
|
-
:reason => "Trying opposite value that is the last remaining results in three-in-a-row",
|
686
|
-
:dir => col_dim()
|
773
|
+
result = method(callback_method).call(
|
774
|
+
:idx => row_idx, :v_s => v_s
|
687
775
|
)
|
688
|
-
|
776
|
+
|
777
|
+
if (result[:verdict])
|
778
|
+
perform_and_append_move(
|
779
|
+
:coord => row.get_coord(x),
|
780
|
+
:val => oppose_v,
|
781
|
+
:reason => result[:reason],
|
782
|
+
:dir => col_dim()
|
783
|
+
)
|
784
|
+
return
|
689
785
|
end
|
690
786
|
end
|
691
787
|
|
@@ -693,19 +789,18 @@ module Binary_Puzzle_Solver
|
|
693
789
|
end
|
694
790
|
|
695
791
|
def validate_rows()
|
696
|
-
# TODO
|
697
|
-
complete_rows_map = Hash.new
|
698
|
-
|
699
792
|
is_final = true
|
700
793
|
|
701
794
|
dim_range(row_dim()).each do |row_idx|
|
702
795
|
row = get_row_handle(row_idx)
|
703
|
-
ret = row.validate(
|
796
|
+
ret = row.validate(:foo => false)
|
704
797
|
is_final &&= ret[:is_final]
|
705
798
|
end
|
706
799
|
|
707
800
|
return is_final
|
708
801
|
end
|
802
|
+
|
803
|
+
private :_do_values_have_a_three_in_a_row, :_generic_check_try_placing_last_digit, :_are_values_duplicates
|
709
804
|
end
|
710
805
|
|
711
806
|
class RowHandle
|
@@ -719,8 +814,14 @@ module Binary_Puzzle_Solver
|
|
719
814
|
return view.get_row_summary(:idx => idx, :dim => row_dim());
|
720
815
|
end
|
721
816
|
|
817
|
+
def self.calc_iter_of_states_str(iter)
|
818
|
+
return iter.map { |v| Cell.get_state_char(v) }.join('')
|
819
|
+
end
|
820
|
+
|
722
821
|
def get_string()
|
723
|
-
return
|
822
|
+
return RowHandle.calc_iter_of_states_str(
|
823
|
+
iter_of_handles().map { |cell_h| cell_h.get_state() }
|
824
|
+
)
|
724
825
|
end
|
725
826
|
|
726
827
|
def col_dim()
|
@@ -770,21 +871,12 @@ module Binary_Puzzle_Solver
|
|
770
871
|
x.get_state() == v }.map { |h| h.x }
|
771
872
|
end
|
772
873
|
|
773
|
-
def check_for_duplicated(
|
874
|
+
def check_for_duplicated()
|
774
875
|
summary = get_summary()
|
775
876
|
|
776
877
|
if not summary.are_both_not_exceeded() then
|
777
878
|
raise GameIntegrityException, "Value exceeded"
|
778
879
|
elsif summary.are_both_full() then
|
779
|
-
s = get_string()
|
780
|
-
complete_rows_map[s] ||= []
|
781
|
-
dups = complete_rows_map[s]
|
782
|
-
dups << idx
|
783
|
-
if (dups.length > 1)
|
784
|
-
i, j = dups[0], dups[1]
|
785
|
-
raise GameIntegrityException, \
|
786
|
-
"Duplicate Rows - #{i} and #{j}"
|
787
|
-
end
|
788
880
|
return true
|
789
881
|
else
|
790
882
|
return false
|
@@ -823,11 +915,9 @@ module Binary_Puzzle_Solver
|
|
823
915
|
end
|
824
916
|
|
825
917
|
def validate(params)
|
826
|
-
complete_rows_map = params[:complete_rows_map]
|
827
|
-
|
828
918
|
check_for_too_many_consecutive()
|
829
919
|
|
830
|
-
return { :is_final => check_for_duplicated(
|
920
|
+
return { :is_final => check_for_duplicated(), };
|
831
921
|
end
|
832
922
|
end
|
833
923
|
|
data/test/deduction.rb
CHANGED
@@ -444,6 +444,102 @@ EOF
|
|
444
444
|
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
445
445
|
end
|
446
446
|
|
447
|
+
def get_6x6_very_hard_board_1__initial()
|
448
|
+
input_str = <<'EOF'
|
449
|
+
| 1 |
|
450
|
+
|00 1 |
|
451
|
+
|0 |
|
452
|
+
| |
|
453
|
+
| 1 |
|
454
|
+
| 0 |
|
455
|
+
EOF
|
456
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
457
|
+
end
|
458
|
+
|
459
|
+
def get_6x6_very_hard_board_1__intermediate_1()
|
460
|
+
input_str = <<'EOF'
|
461
|
+
|101010|
|
462
|
+
|001101|
|
463
|
+
|010011|
|
464
|
+
|1 010|
|
465
|
+
| 10 |
|
466
|
+
| 1010 |
|
467
|
+
EOF
|
468
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
469
|
+
end
|
470
|
+
|
471
|
+
def get_6x6_very_hard_board_1__final()
|
472
|
+
input_str = <<'EOF'
|
473
|
+
|101010|
|
474
|
+
|001101|
|
475
|
+
|010011|
|
476
|
+
|110010|
|
477
|
+
|101100|
|
478
|
+
|010101|
|
479
|
+
EOF
|
480
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
481
|
+
end
|
482
|
+
|
483
|
+
def get_6x6_very_hard_board_2__initial()
|
484
|
+
input_str = <<'EOF'
|
485
|
+
| 0 |
|
486
|
+
| |
|
487
|
+
|1 |
|
488
|
+
| 0 0 |
|
489
|
+
|1 0 |
|
490
|
+
| 0 0|
|
491
|
+
EOF
|
492
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
493
|
+
end
|
494
|
+
|
495
|
+
def get_6x6_very_hard_board_2__final()
|
496
|
+
input_str = <<'EOF'
|
497
|
+
|001011|
|
498
|
+
|010011|
|
499
|
+
|110100|
|
500
|
+
|001101|
|
501
|
+
|110010|
|
502
|
+
|101100|
|
503
|
+
EOF
|
504
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
505
|
+
end
|
506
|
+
|
507
|
+
def get_12x12_very_hard_board_1__initial()
|
508
|
+
input_str = <<'EOF'
|
509
|
+
| 00 1 |
|
510
|
+
| 1 1 |
|
511
|
+
| 0 0 0 0|
|
512
|
+
| 0 |
|
513
|
+
| 11 1 1 0 |
|
514
|
+
| 11 0 00 |
|
515
|
+
| 1 |
|
516
|
+
|1 00 0 |
|
517
|
+
| |
|
518
|
+
| 1 1 |
|
519
|
+
| 0 0 0 0|
|
520
|
+
| 10 0 |
|
521
|
+
EOF
|
522
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
523
|
+
end
|
524
|
+
|
525
|
+
def get_12x12_very_hard_board_1__intermediate_1()
|
526
|
+
input_str = <<'EOF'
|
527
|
+
|110100100110|
|
528
|
+
|001101001011|
|
529
|
+
|110010110100|
|
530
|
+
|100100101101|
|
531
|
+
|011011010010|
|
532
|
+
|011001001101|
|
533
|
+
|100110110010|
|
534
|
+
|101001010011|
|
535
|
+
|010110101100|
|
536
|
+
|001101011001|
|
537
|
+
|110011010010|
|
538
|
+
|001010101101|
|
539
|
+
EOF
|
540
|
+
return Binary_Puzzle_Solver.gen_board_from_string_v1(input_str)
|
541
|
+
end
|
542
|
+
|
447
543
|
describe "construct_board" do
|
448
544
|
it "6*6 Easy board No. 1 should" do
|
449
545
|
|
@@ -995,4 +1091,97 @@ describe "rudimentary_deduction" do
|
|
995
1091
|
|
996
1092
|
compare_boards(board, final_board)
|
997
1093
|
end
|
1094
|
+
|
1095
|
+
it "Solving 6*6 Very Hard board No. 1 should" do
|
1096
|
+
|
1097
|
+
board = get_6x6_very_hard_board_1__initial()
|
1098
|
+
|
1099
|
+
board.add_to_iters_quota(1_000_000_000);
|
1100
|
+
|
1101
|
+
board.try_to_solve_using(
|
1102
|
+
:methods => [
|
1103
|
+
:check_and_handle_sequences_in_row,
|
1104
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
1105
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
1106
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
1107
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
1108
|
+
]
|
1109
|
+
);
|
1110
|
+
|
1111
|
+
intermediate_board = get_6x6_very_hard_board_1__intermediate_1()
|
1112
|
+
|
1113
|
+
# binding.pry
|
1114
|
+
|
1115
|
+
compare_boards(board, intermediate_board)
|
1116
|
+
|
1117
|
+
board.try_to_solve_using(
|
1118
|
+
:methods => [
|
1119
|
+
:check_and_handle_sequences_in_row,
|
1120
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
1121
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
1122
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
1123
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
1124
|
+
:check_try_placing_last_of_certain_digit_in_row_to_avoid_dups,
|
1125
|
+
]
|
1126
|
+
);
|
1127
|
+
|
1128
|
+
board.get_cell_state(
|
1129
|
+
Binary_Puzzle_Solver::Coord.new(:x => 1, :y => 3)
|
1130
|
+
).should == ONE
|
1131
|
+
board.get_cell_state(
|
1132
|
+
Binary_Puzzle_Solver::Coord.new(:x => 2, :y => 3)
|
1133
|
+
).should == ZERO
|
1134
|
+
|
1135
|
+
final_board = get_6x6_very_hard_board_1__final()
|
1136
|
+
|
1137
|
+
compare_boards(board, final_board)
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
it "Solving 6*6 Very Hard board No. 2 should" do
|
1141
|
+
|
1142
|
+
board = get_6x6_very_hard_board_2__initial()
|
1143
|
+
|
1144
|
+
board.add_to_iters_quota(1_000_000_000);
|
1145
|
+
|
1146
|
+
board.try_to_solve_using(
|
1147
|
+
:methods => [
|
1148
|
+
:check_and_handle_sequences_in_row,
|
1149
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
1150
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
1151
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
1152
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
1153
|
+
:check_try_placing_last_of_certain_digit_in_row_to_avoid_dups,
|
1154
|
+
]
|
1155
|
+
);
|
1156
|
+
|
1157
|
+
final_board = get_6x6_very_hard_board_2__final()
|
1158
|
+
|
1159
|
+
# binding.pry
|
1160
|
+
|
1161
|
+
compare_boards(board, final_board)
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
it "Solving 12*12 Very Hard board No. 1 should" do
|
1165
|
+
|
1166
|
+
board = get_12x12_very_hard_board_1__initial()
|
1167
|
+
|
1168
|
+
board.add_to_iters_quota(1_000_000_000);
|
1169
|
+
|
1170
|
+
board.try_to_solve_using(
|
1171
|
+
:methods => [
|
1172
|
+
:check_and_handle_sequences_in_row,
|
1173
|
+
:check_and_handle_known_unknown_sameknown_in_row,
|
1174
|
+
:check_and_handle_cells_of_one_value_in_row_were_all_found,
|
1175
|
+
:check_exceeded_numbers_while_accounting_for_two_unknown_gaps,
|
1176
|
+
:check_try_placing_last_of_certain_digit_in_row,
|
1177
|
+
:check_try_placing_last_of_certain_digit_in_row_to_avoid_dups,
|
1178
|
+
]
|
1179
|
+
);
|
1180
|
+
|
1181
|
+
final_board = get_12x12_very_hard_board_1__intermediate_1()
|
1182
|
+
|
1183
|
+
# binding.pry
|
1184
|
+
|
1185
|
+
compare_boards(board, final_board)
|
1186
|
+
end
|
998
1187
|
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.4
|
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: 2013-
|
12
|
+
date: 2013-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: launchy
|
@@ -64,6 +64,8 @@ files:
|
|
64
64
|
- lib/binary_puzzle_solver.rb
|
65
65
|
- lib/binary_puzzle_solver/base.rb
|
66
66
|
- lib/binary_puzzle_solver/version.rb
|
67
|
+
- test/data/boards/12x12_hard_no_1.binpuz.board
|
68
|
+
- test/data/boards/2013-06-07-12x12_very_hard.binpuz.board
|
67
69
|
- test/deduction.rb
|
68
70
|
homepage: http://www.shlomifish.org/open-source/projects/japanese-puzzle-games/binary-puzzle/
|
69
71
|
licenses: []
|
@@ -90,4 +92,6 @@ signing_key:
|
|
90
92
|
specification_version: 3
|
91
93
|
summary: A solver for http://www.binarypuzzle.com/ instances
|
92
94
|
test_files:
|
95
|
+
- test/data/boards/12x12_hard_no_1.binpuz.board
|
96
|
+
- test/data/boards/2013-06-07-12x12_very_hard.binpuz.board
|
93
97
|
- test/deduction.rb
|