binary_puzzle_solver 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|