multi-puzzle-solver 0.9.22__tar.gz → 0.9.25__tar.gz

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.

Potentially problematic release.


This version of multi-puzzle-solver might be problematic. Click here for more details.

Files changed (107) hide show
  1. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/PKG-INFO +323 -4
  2. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/README.md +322 -3
  3. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/multi_puzzle_solver.egg-info/PKG-INFO +323 -4
  4. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/multi_puzzle_solver.egg-info/SOURCES.txt +9 -0
  5. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/__init__.py +5 -1
  6. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/core/utils.py +157 -2
  7. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/core/utils_ortools.py +6 -10
  8. multi_puzzle_solver-0.9.25/src/puzzle_solver/puzzles/binairo/binairo.py +98 -0
  9. multi_puzzle_solver-0.9.25/src/puzzle_solver/puzzles/flip/flip.py +48 -0
  10. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/lits/lits.py +2 -28
  11. multi_puzzle_solver-0.9.25/src/puzzle_solver/puzzles/palisade/palisade.py +104 -0
  12. multi_puzzle_solver-0.9.25/src/puzzle_solver/puzzles/rectangles/rectangles.py +130 -0
  13. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/slitherlink/slitherlink.py +12 -131
  14. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/yin_yang/parse_map/parse_map.py +4 -1
  15. multi_puzzle_solver-0.9.25/tests/test_binairo.py +126 -0
  16. multi_puzzle_solver-0.9.25/tests/test_flip.py +2 -0
  17. multi_puzzle_solver-0.9.25/tests/test_palisade.py +157 -0
  18. multi_puzzle_solver-0.9.25/tests/test_rectangles.py +127 -0
  19. multi_puzzle_solver-0.9.25/tests/test_utils.py +11 -0
  20. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/pyproject.toml +0 -0
  21. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/setup.cfg +0 -0
  22. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/multi_puzzle_solver.egg-info/dependency_links.txt +0 -0
  23. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/multi_puzzle_solver.egg-info/requires.txt +0 -0
  24. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/multi_puzzle_solver.egg-info/top_level.txt +0 -0
  25. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/aquarium/aquarium.py +0 -0
  26. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/battleships/battleships.py +0 -0
  27. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/black_box/black_box.py +0 -0
  28. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/bridges/bridges.py +0 -0
  29. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/chess_range/chess_melee.py +0 -0
  30. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/chess_range/chess_range.py +0 -0
  31. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/chess_range/chess_solo.py +0 -0
  32. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/dominosa/dominosa.py +0 -0
  33. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/filling/filling.py +0 -0
  34. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/galaxies/galaxies.py +0 -0
  35. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/galaxies/parse_map/parse_map.py +0 -0
  36. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/guess/guess.py +0 -0
  37. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/inertia/inertia.py +0 -0
  38. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/inertia/parse_map/parse_map.py +0 -0
  39. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/inertia/tsp.py +0 -0
  40. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/kakurasu/kakurasu.py +0 -0
  41. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/keen/keen.py +0 -0
  42. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/light_up/light_up.py +0 -0
  43. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/magnets/magnets.py +0 -0
  44. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/map/map.py +0 -0
  45. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/minesweeper/minesweeper.py +0 -0
  46. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/mosaic/mosaic.py +0 -0
  47. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/nonograms/nonograms.py +0 -0
  48. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/norinori/norinori.py +0 -0
  49. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/pearl/pearl.py +0 -0
  50. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/range/range.py +0 -0
  51. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/signpost/signpost.py +0 -0
  52. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/singles/singles.py +0 -0
  53. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/slant/parse_map/parse_map.py +0 -0
  54. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/slant/slant.py +0 -0
  55. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/star_battle/star_battle.py +0 -0
  56. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/star_battle/star_battle_shapeless.py +0 -0
  57. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/stitches/parse_map/parse_map.py +0 -0
  58. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/stitches/stitches.py +0 -0
  59. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/sudoku/sudoku.py +0 -0
  60. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/tents/tents.py +0 -0
  61. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/thermometers/thermometers.py +0 -0
  62. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/towers/towers.py +0 -0
  63. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/tracks/tracks.py +0 -0
  64. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/undead/undead.py +0 -0
  65. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/unequal/unequal.py +0 -0
  66. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/unruly/unruly.py +0 -0
  67. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/puzzles/yin_yang/yin_yang.py +0 -0
  68. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/src/puzzle_solver/utils/visualizer.py +0 -0
  69. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_aquarium.py +0 -0
  70. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_battleships.py +0 -0
  71. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_black_box.py +0 -0
  72. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_bridges.py +0 -0
  73. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_chess_melee.py +0 -0
  74. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_chess_range.py +0 -0
  75. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_chess_solo.py +0 -0
  76. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_dominosa.py +0 -0
  77. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_filling.py +0 -0
  78. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_galaxies.py +0 -0
  79. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_guess.py +0 -0
  80. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_inertia.py +0 -0
  81. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_kakurasu.py +0 -0
  82. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_keen.py +0 -0
  83. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_light_up.py +0 -0
  84. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_lits.py +0 -0
  85. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_magnets.py +0 -0
  86. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_map.py +0 -0
  87. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_minesweeper.py +0 -0
  88. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_mosaic.py +0 -0
  89. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_nonograms.py +0 -0
  90. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_norinori.py +0 -0
  91. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_pearl.py +0 -0
  92. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_range.py +0 -0
  93. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_signpost.py +0 -0
  94. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_singles.py +0 -0
  95. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_slant.py +0 -0
  96. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_slitherlink.py +0 -0
  97. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_star_battle.py +0 -0
  98. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_stitches.py +0 -0
  99. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_sudoku.py +0 -0
  100. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_tents.py +0 -0
  101. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_thermometers.py +0 -0
  102. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_towers.py +0 -0
  103. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_tracks.py +0 -0
  104. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_undead.py +0 -0
  105. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_unequal.py +0 -0
  106. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_unruly.py +0 -0
  107. {multi_puzzle_solver-0.9.22 → multi_puzzle_solver-0.9.25}/tests/test_yin_yang.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multi-puzzle-solver
3
- Version: 0.9.22
3
+ Version: 0.9.25
4
4
  Summary: Efficient solvers for numerous popular and esoteric logic puzzles using CP-SAT
5
5
  Author: Ar-Kareem
6
6
  Project-URL: Homepage, https://github.com/Ar-Kareem/puzzle_solver
@@ -315,6 +315,23 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
315
315
  </a>
316
316
  </td>
317
317
  </tr>
318
+ <tr>
319
+ <td align="center">
320
+ <a href="#binairo-puzzle-type-41"><b>Binairo</b><br><br>
321
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/binairo_solved.png" alt="Binairo" width="140">
322
+ </a>
323
+ </td>
324
+ <td align="center">
325
+ <a href="#rectangles-puzzle-type-42"><b>Rectangles</b><br><br>
326
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/rectangles_solved.png" alt="Rectangles" width="140">
327
+ </a>
328
+ </td>
329
+ <td align="center">
330
+ <a href="#palisade-puzzle-type-43"><b>Palisade</b><br><br>
331
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/palisade_solved.png" alt="Palisade" width="140">
332
+ </a>
333
+ </td>
334
+ </tr>
318
335
  </table>
319
336
 
320
337
  </div>
@@ -369,6 +386,9 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
369
386
  - [Norinori (Puzzle Type #38)](#norinori-puzzle-type-38)
370
387
  - [Slitherlink (Puzzle Type #39)](#slitherlink-puzzle-type-39)
371
388
  - [Yin-Yang (Puzzle Type #40)](#yin-yang-puzzle-type-40)
389
+ - [Binairo (Puzzle Type #41)](#binairo-puzzle-type-41)
390
+ - [Rectangles (Puzzle Type #42)](#rectangles-puzzle-type-42)
391
+ - [Palisade (Puzzle Type #43)](#palisade-puzzle-type-43)
372
392
  - [Why SAT / CP-SAT?](#why-sat--cp-sat)
373
393
  - [Testing](#testing)
374
394
  - [Contributing](#contributing)
@@ -3303,9 +3323,13 @@ Applying the solution to the puzzle visually:
3303
3323
 
3304
3324
  ## Slitherlink (Puzzle Type #39)
3305
3325
 
3306
- Also known as Fences and Loop the Loop
3326
+ Also known as Fences, Loop the Loop, and Loopy
3327
+
3328
+ * [**Play online 1**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/loopy.html)
3329
+
3330
+ * [**Play online 2**](https://www.puzzle-loop.com)
3307
3331
 
3308
- * [**Play online**](https://www.puzzle-loop.com)
3332
+ * [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/loopy.html#loopy)
3309
3333
 
3310
3334
  * [**Solver Code**][39]
3311
3335
 
@@ -3412,7 +3436,6 @@ Applying the solution to the puzzle visually:
3412
3436
 
3413
3437
  ---
3414
3438
 
3415
-
3416
3439
  ## Yin-Yang (Puzzle Type #40)
3417
3440
 
3418
3441
  * [**Play online**](https://www.puzzle-yin-yang.com)
@@ -3503,6 +3526,299 @@ Applying the solution to the puzzle visually:
3503
3526
 
3504
3527
  ---
3505
3528
 
3529
+ ## Binairo (Puzzle Type #41)
3530
+
3531
+ * [**Play online**](https://www.puzzle-binairo.com)
3532
+
3533
+ * [**Solver Code**][41]
3534
+
3535
+ <details>
3536
+ <summary><strong>Rules</strong></summary>
3537
+
3538
+ Binairo is played on a rectangular grid with no standard size. Some cells start out filled with black or white circles. The rest of the cells are empty. The goal is to place circles in all cells in such a way that:
3539
+
3540
+ 1. Each row and each column must contain an equal number of white and black circles.
3541
+ 2. More than two circles of the same color can't be adjacent.
3542
+ 3. Each row and column is unique.
3543
+
3544
+ </details>
3545
+
3546
+ **Unsolved puzzle**
3547
+
3548
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/binairo_unsolved.png" alt="Binairo unsolved" width="500">
3549
+
3550
+ Code to utilize this package and solve the puzzle:
3551
+
3552
+ ```python
3553
+ import numpy as np
3554
+ from puzzle_solver import binairo_solver as solver
3555
+ board = np.array([
3556
+ [' ', ' ', ' ', ' ', 'W', ' ', ' ', ' ', 'W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', 'W'],
3557
+ [' ', 'W', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', 'W', ' ', ' ', 'B', ' ', ' ', ' ', 'B', ' '],
3558
+ [' ', 'W', ' ', ' ', ' ', 'W', ' ', 'W', 'W', ' ', ' ', ' ', 'B', ' ', ' ', 'W', ' ', ' ', ' ', ' '],
3559
+ ['B', ' ', ' ', 'W', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
3560
+ ['B', ' ', ' ', ' ', 'W', ' ', ' ', ' ', ' ', 'B', ' ', 'W', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'W'],
3561
+ [' ', ' ', 'W', ' ', ' ', 'W', ' ', ' ', ' ', ' ', 'W', ' ', ' ', ' ', ' ', ' ', ' ', 'W', ' ', ' '],
3562
+ ['W', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', 'B', ' ', ' ', 'B', 'B', ' ', ' ', 'W', ' ', 'B', ' '],
3563
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', 'W', ' ', ' ', ' '],
3564
+ [' ', ' ', ' ', ' ', 'W', ' ', 'B', ' ', 'W', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
3565
+ [' ', 'W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W', ' ', ' ', ' ', 'W', 'W', ' ', ' ', ' '],
3566
+ [' ', ' ', 'B', ' ', ' ', ' ', 'B', ' ', 'B', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
3567
+ [' ', 'W', 'B', ' ', 'W', ' ', 'B', ' ', ' ', ' ', ' ', ' ', 'W', 'W', ' ', 'B', ' ', ' ', 'B', ' '],
3568
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'B', 'B'],
3569
+ [' ', 'B', ' ', ' ', ' ', ' ', 'W', ' ', 'W', 'W', ' ', ' ', 'W', ' ', ' ', ' ', 'W', ' ', ' ', ' '],
3570
+ [' ', ' ', 'W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W', 'W', ' ', ' ', 'W', 'W', ' '],
3571
+ [' ', 'B', ' ', 'B', 'W', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
3572
+ [' ', 'B', ' ', ' ', ' ', 'W', ' ', ' ', ' ', 'W', ' ', ' ', 'B', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
3573
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ', ' ', 'W', ' ', ' ', ' ', 'W'],
3574
+ [' ', ' ', ' ', 'B', 'B', ' ', ' ', 'W', ' ', 'W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' ', ' '],
3575
+ ['B', ' ', 'B', 'B', ' ', ' ', ' ', ' ', ' ', 'W', ' ', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' ']
3576
+ ])
3577
+ binst = solver.Board(board=board)
3578
+ solutions = binst.solve_and_print()
3579
+ ```
3580
+
3581
+ **Script Output**
3582
+
3583
+ ```python
3584
+ Solution found
3585
+ [
3586
+ [ 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W' ],
3587
+ [ 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W' ],
3588
+ [ 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'B' ],
3589
+ [ 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'B' ],
3590
+ [ 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'B', 'W' ],
3591
+ [ 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'W', 'B' ],
3592
+ [ 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'B', 'W' ],
3593
+ [ 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'W', 'B' ],
3594
+ [ 'W', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'W' ],
3595
+ [ 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B' ],
3596
+ [ 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'W' ],
3597
+ [ 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W' ],
3598
+ [ 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'B' ],
3599
+ [ 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'W' ],
3600
+ [ 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B' ],
3601
+ [ 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W' ],
3602
+ [ 'W', 'B', 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B' ],
3603
+ [ 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'B', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'W' ],
3604
+ [ 'W', 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B' ],
3605
+ [ 'B', 'W', 'B', 'B', 'W', 'B', 'W', 'B', 'W', 'W', 'B', 'B', 'W', 'W', 'B', 'W', 'B', 'W', 'W', 'B' ],
3606
+ ]
3607
+ Solutions found: 1
3608
+ status: OPTIMAL
3609
+ Time taken: 0.03 seconds
3610
+ ```
3611
+
3612
+ **Solved puzzle**
3613
+
3614
+ Applying the solution to the puzzle visually:
3615
+
3616
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/binairo_solved.png" alt="Binairo solved" width="500">
3617
+
3618
+ ---
3619
+
3620
+ ## Rectangles (Puzzle Type #42)
3621
+
3622
+ Also called "Shikaku".
3623
+
3624
+ * [**Play online**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/rect.html)
3625
+
3626
+ * [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/rect.html#rect)
3627
+
3628
+ * [**Solver Code**][42]
3629
+
3630
+ <details>
3631
+ <summary><strong>Rules</strong></summary>
3632
+
3633
+ You have a grid of squares, with numbers written in some (but not all) of the squares. Your task is to subdivide the grid into rectangles of various sizes, such that both:
3634
+
3635
+ - (a) every rectangle contains exactly one numbered square
3636
+ - (b) the area of each rectangle is equal to the number written in its numbered square.
3637
+
3638
+
3639
+ </details>
3640
+
3641
+ **Unsolved puzzle**
3642
+
3643
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/rectangles_unsolved.png" alt="Rectangles unsolved" width="500">
3644
+
3645
+ Code to utilize this package and solve the puzzle:
3646
+
3647
+ ```python
3648
+ import numpy as np
3649
+ from puzzle_solver import rectangles_solver as solver
3650
+ board = np.array([
3651
+ ['3', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '15',' ', ' ', ' ', ' ' ],
3652
+ [' ', ' ', '2', '2', ' ', ' ', ' ', ' ', ' ', ' ', '11',' ', ' ', ' ', ' ', ' ', ' ', '3', '2' ],
3653
+ [' ', ' ', ' ', ' ', '2', ' ', ' ', ' ', '11',' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ' ],
3654
+ [' ', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', '6', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3655
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3656
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3657
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3658
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '28','4', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3659
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '10',' ', '10',' ', ' ', ' ', ' ', '45',' ' ],
3660
+ [' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3661
+ [' ', '22',' ', ' ', ' ', ' ', ' ', '28',' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '17'],
3662
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3663
+ [' ', '8', '3', ' ', ' ', '2', '2', ' ', ' ', ' ', '5', ' ', ' ', '4', ' ', ' ', ' ', ' ', ' ' ],
3664
+ [' ', ' ', ' ', ' ', '4', ' ', ' ', '8', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', ' ', ' ' ],
3665
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '3', ' ' ],
3666
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3667
+ ['2', ' ', ' ', ' ', '12',' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3668
+ ['2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ],
3669
+ [' ', ' ', '3', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '60',' ', ' ', ' ', ' ', ' ', '4', ' ' ],
3670
+ ])
3671
+ binst = solver.Board(board=board)
3672
+ solutions = binst.solve_and_print()
3673
+ ```
3674
+
3675
+ **Script Output**
3676
+
3677
+ ```python
3678
+ Solution found
3679
+ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
3680
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
3681
+ ┌───────────┬───────────────────────────────────────────────────────────┬───┐
3682
+ 0│ 3 │ 15 │ │
3683
+ ├───────┬───┼───┬───────────────────────────────────────────┬───────────┤ │
3684
+ 1│ │ 2 │ 2 │ 11 │ 3 │ 2 │
3685
+ │ │ │ ├───┬───────────────────────────────────────┴───┬───────┼───┤
3686
+ 2│ │ │ │ 2 │ 11 │ 2 │ │
3687
+ │ ├───┴───┤ ├───────────────────────┬───┬───┬───────────┴───────┤ │
3688
+ 3│ │ 2 │ │ 6 │ │ │ │ │
3689
+ │ ├───────┴───┴───────────────┬───┬───┤ │ │ │ │
3690
+ 4│ │ │ │ │ 3 │ │ │ │
3691
+ │ │ │ │ │ │ │ │ │
3692
+ 5│ │ │ │ 2 │ │ │ │ │
3693
+ │ │ │ ├───┴───┤ │ │ │
3694
+ 6│ │ │ │ 2 │ │ │ │
3695
+ │ │ │ ├───────┤ │ │ │
3696
+ 7│ │ 28 │ 4 │ │ │ │ │
3697
+ │ ├───┬───────────────────────┴───┤ │ │ │ │
3698
+ 8│ │ │ │10 │10 │ 45 │ │
3699
+ │ │ │ │ │ │ │ │
3700
+ 9│ │ 3 │ │ │ │ │ │
3701
+ │ │ │ │ │ │ │ │
3702
+ 10│ 22 │ │ 28 │ │ │ │17 │
3703
+ │ ├───┤ │ │ │ │ │
3704
+ 11│ │ │ │ │ │ │ │
3705
+ ├───────┤ ├───────┬───┬───┬───────────┴───────┤ ├───────────────┬───┤ │
3706
+ 12│ 8 │ 3 │ │ 2 │ 2 │ 5 │ │ 4 │ │ │
3707
+ │ │ │ │ │ ├───────────────────┴───┴───────┬───────┤ │ │
3708
+ 13│ │ │ 4 │ │ │ 8 │ 2 │ │ │
3709
+ │ ├───┴───────┼───┴───┴───────────────────────────────┴───────┤ │ │
3710
+ 14│ │ │ │ 3 │ │
3711
+ │ │ │ ├───┤ │
3712
+ 15│ │ │ │ │ │
3713
+ ├───────┤ │ │ │ │
3714
+ 16│ 2 │ 12 │ │ │ │
3715
+ ├───────┤ │ │ │ │
3716
+ 17│ 2 │ │ │ │ │
3717
+ ├───────┴───┬───────┤ │ │ │
3718
+ 18│ 3 │ 2 │ 60 │ 4 │ │
3719
+ └───────────┴───────┴───────────────────────────────────────────────┴───┴───┘
3720
+ Solutions found: 1
3721
+ status: OPTIMAL
3722
+ Time taken: 0.01 seconds
3723
+ ```
3724
+
3725
+ **Solved puzzle**
3726
+
3727
+ Applying the solution to the puzzle visually:
3728
+
3729
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/rectangles_solved.png" alt="Rectangles solved" width="500">
3730
+
3731
+ ---
3732
+
3733
+
3734
+ ## Palisade (Puzzle Type #43)
3735
+
3736
+ * [**Play online**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/palisade.html)
3737
+
3738
+ * [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/palisade.html#palisade)
3739
+
3740
+ * [**Solver Code**][42]
3741
+
3742
+ <details>
3743
+ <summary><strong>Rules</strong></summary>
3744
+
3745
+ You're given a grid of N squares and a region size M, some of which contain numbers. Your goal is to subdivide the grid into (N/M) contiguous regions, where every region is of size M, such that each square containing a number is adjacent to exactly that many edges (including those between the inside and the outside of the grid).
3746
+
3747
+ </details>
3748
+
3749
+ **Unsolved puzzle**
3750
+
3751
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/palisade_unsolved.png" alt="Palisade unsolved" width="500">
3752
+
3753
+ Code to utilize this package and solve the puzzle:
3754
+
3755
+ (Note: it takes a few seconds for the model to be built if the region size is larger than 8 and around 10 seconds for a region size of 10)
3756
+
3757
+ ```python
3758
+ import numpy as np
3759
+ from puzzle_solver import palisade_solver as solver
3760
+ board = np.array([
3761
+ ['2', ' ', ' ', ' ', ' ', '3', ' ', ' ', '1', '1', '3', ' ', ' ', ' ', ' '],
3762
+ ['3', '2', '1', ' ', '2', '3', ' ', ' ', ' ', ' ', ' ', '2', ' ', '0', ' '],
3763
+ [' ', ' ', ' ', '1', '1', ' ', ' ', '1', ' ', ' ', ' ', '1', ' ', ' ', ' '],
3764
+ [' ', '3', '2', ' ', ' ', ' ', ' ', '2', '3', ' ', ' ', ' ', '1', ' ', ' '],
3765
+ [' ', '0', '1', ' ', '2', ' ', ' ', '0', ' ', ' ', ' ', '1', ' ', '3', '2'],
3766
+ ['1', '0', ' ', ' ', ' ', '2', '2', ' ', '2', ' ', '3', ' ', '0', '2', ' '],
3767
+ [' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' '],
3768
+ [' ', '1', ' ', ' ', ' ', '3', '1', ' ', '1', ' ', ' ', ' ', ' ', '1', ' '],
3769
+ [' ', ' ', ' ', '0', ' ', ' ', '0', ' ', ' ', '1', '2', ' ', ' ', ' ', '3'],
3770
+ [' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', ' ', '2', ' ', ' ', '1', '2', '1'],
3771
+ [' ', ' ', ' ', ' ', '1', ' ', '2', '3', '1', ' ', ' ', ' ', '2', ' ', '1'],
3772
+ ['2', ' ', '1', ' ', '2', '2', '1', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' '],
3773
+ ])
3774
+ binst = solver.Board(board, region_size=10)
3775
+ solutions = binst.solve_and_print()
3776
+ ```
3777
+
3778
+ **Script Output**
3779
+
3780
+ ```python
3781
+ Solution found
3782
+ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
3783
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
3784
+ ┌───────────────────┬───────────────────────┬───────────────┐
3785
+ 0│ 2 · · · · │ 3 · · 1 1 3 │ · · · · │
3786
+ │ ┌───────────┐ ├───────┬───┐ ┌───┴───┐ │
3787
+ 1│ 3 │ 2 1 · │ 2 │ 3 · │ · │ · · │ · 2 │ · 0 · │
3788
+ ├───┘ │ └───┐ │ └───┐ └───┐ └───┐ │
3789
+ 2│ · · · 1 │ 1 · │ · │ 1 · │ · · │ 1 · │ · · │
3790
+ │ ┌───┐ │ ┌───┘ │ ┌───┴───────┘ └───┐ │
3791
+ 3│ · │ 3 │ 2 · │ · │ · · │ 2 │ 3 · · · 1 · │ · │
3792
+ ├───┘ └───────┼───┘ ┌───┘ └───┬───────────────┬───┴───┤
3793
+ 4│ · 0 1 · │ 2 · │ · 0 · │ · · 1 · │ 3 2 │
3794
+ │ ┌───┘ │ │ ┌───┐ └───┐ │
3795
+ 5│ 1 0 · │ · · 2 │ 2 · 2 │ · │ 3 │ · 0 2 │ · │
3796
+ │ ┌───┴───────────┼───┬───────┴───┤ ├───┐ │ │
3797
+ 6│ · · │ · · · 3 │ · │ · · 2 │ · │ · │ · · │ · │
3798
+ ├───────┘ ┌───────────┤ └───┐ │ │ └───────┘ │
3799
+ 7│ · 1 · │ · · 3 │ 1 · │ 1 · │ · │ · · 1 · │
3800
+ │ ┌───┘ ┌───┘ │ │ └───────┐ ┌───┤
3801
+ 8│ · · │ · 0 · │ · 0 · │ · 1 │ 2 · · │ · │ 3 │
3802
+ │ ┌───┘ ┌───┤ ├───┐ └───┐ ├───┘ │
3803
+ 9│ · │ · · · │ · │ · 1 · │ · │ 2 · │ · 1 │ 2 1 │
3804
+ ├───┤ ┌───────┘ ├───────┐ │ └───┐ │ │ │
3805
+ 10│ · │ · │ · · 1 │ · 2 │ 3 │ 1 · │ · │ · 2 │ · 1 │
3806
+ │ └───┘ │ └───┘ ├───┴───────┘ │
3807
+ 11│ 2 · 1 · 2 │ 2 1 · · 2 │ · · · · · │
3808
+ └───────────────────┴───────────────────┴───────────────────┘
3809
+ Solutions found: 1
3810
+ status: OPTIMAL
3811
+ Time taken: 11.94 seconds
3812
+ ```
3813
+
3814
+ **Solved puzzle**
3815
+
3816
+ Applying the solution to the puzzle visually:
3817
+
3818
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/palisade_solved.png" alt="Palisade solved" width="500">
3819
+
3820
+ ---
3821
+
3506
3822
  ---
3507
3823
 
3508
3824
  ## Why SAT / CP-SAT?
@@ -3594,3 +3910,6 @@ Issues and PRs welcome!
3594
3910
  [38]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/norinori "puzzle_solver/src/puzzle_solver/puzzles/norinori at master · Ar-Kareem/puzzle_solver · GitHub"
3595
3911
  [39]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/slitherlink "puzzle_solver/src/puzzle_solver/puzzles/slitherlink at master · Ar-Kareem/puzzle_solver · GitHub"
3596
3912
  [40]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/yin_yang "puzzle_solver/src/puzzle_solver/puzzles/yin_yang at master · Ar-Kareem/puzzle_solver · GitHub"
3913
+ [41]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/binairo "puzzle_solver/src/puzzle_solver/puzzles/binairo at master · Ar-Kareem/puzzle_solver · GitHub"
3914
+ [42]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/rectangles "puzzle_solver/src/puzzle_solver/puzzles/rectangles at master · Ar-Kareem/puzzle_solver · GitHub"
3915
+ [43]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/palisade "puzzle_solver/src/puzzle_solver/puzzles/palisade at master · Ar-Kareem/puzzle_solver · GitHub"