multi-puzzle-solver 0.9.25__tar.gz → 0.9.27__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.
- {multi_puzzle_solver-0.9.25/src/multi_puzzle_solver.egg-info → multi_puzzle_solver-0.9.27}/PKG-INFO +199 -3
- multi_puzzle_solver-0.9.25/PKG-INFO → multi_puzzle_solver-0.9.27/README.md +4085 -3915
- multi_puzzle_solver-0.9.25/README.md → multi_puzzle_solver-0.9.27/src/multi_puzzle_solver.egg-info/PKG-INFO +4111 -3889
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/multi_puzzle_solver.egg-info/SOURCES.txt +3 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/__init__.py +3 -2
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/core/utils.py +3 -154
- multi_puzzle_solver-0.9.27/src/puzzle_solver/core/utils_visualizer.py +310 -0
- multi_puzzle_solver-0.9.27/src/puzzle_solver/puzzles/flip/flip.py +77 -0
- multi_puzzle_solver-0.9.27/src/puzzle_solver/puzzles/nurikabe/nurikabe.py +126 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/palisade/palisade.py +3 -2
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/rectangles/rectangles.py +2 -2
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/slitherlink/slitherlink.py +2 -1
- multi_puzzle_solver-0.9.27/tests/test_flip.py +73 -0
- multi_puzzle_solver-0.9.27/tests/test_nurikabe.py +92 -0
- multi_puzzle_solver-0.9.25/src/puzzle_solver/puzzles/flip/flip.py +0 -48
- multi_puzzle_solver-0.9.25/tests/test_flip.py +0 -2
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/pyproject.toml +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/setup.cfg +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/multi_puzzle_solver.egg-info/dependency_links.txt +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/multi_puzzle_solver.egg-info/requires.txt +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/multi_puzzle_solver.egg-info/top_level.txt +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/core/utils_ortools.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/aquarium/aquarium.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/battleships/battleships.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/binairo/binairo.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/black_box/black_box.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/bridges/bridges.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/chess_range/chess_melee.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/chess_range/chess_range.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/chess_range/chess_solo.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/dominosa/dominosa.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/filling/filling.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/galaxies/galaxies.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/galaxies/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/guess/guess.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/inertia/inertia.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/inertia/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/inertia/tsp.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/kakurasu/kakurasu.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/keen/keen.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/light_up/light_up.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/lits/lits.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/magnets/magnets.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/map/map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/minesweeper/minesweeper.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/mosaic/mosaic.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/nonograms/nonograms.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/norinori/norinori.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/pearl/pearl.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/range/range.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/signpost/signpost.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/singles/singles.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/slant/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/slant/slant.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/star_battle/star_battle.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/star_battle/star_battle_shapeless.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/stitches/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/stitches/stitches.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/sudoku/sudoku.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/tents/tents.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/thermometers/thermometers.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/towers/towers.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/tracks/tracks.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/undead/undead.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/unequal/unequal.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/unruly/unruly.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/yin_yang/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/puzzles/yin_yang/yin_yang.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/src/puzzle_solver/utils/visualizer.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_aquarium.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_battleships.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_binairo.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_black_box.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_bridges.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_chess_melee.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_chess_range.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_chess_solo.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_dominosa.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_filling.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_galaxies.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_guess.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_inertia.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_kakurasu.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_keen.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_light_up.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_lits.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_magnets.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_map.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_minesweeper.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_mosaic.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_nonograms.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_norinori.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_palisade.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_pearl.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_range.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_rectangles.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_signpost.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_singles.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_slant.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_slitherlink.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_star_battle.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_stitches.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_sudoku.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_tents.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_thermometers.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_towers.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_tracks.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_undead.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_unequal.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_unruly.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_utils.py +0 -0
- {multi_puzzle_solver-0.9.25 → multi_puzzle_solver-0.9.27}/tests/test_yin_yang.py +0 -0
{multi_puzzle_solver-0.9.25/src/multi_puzzle_solver.egg-info → multi_puzzle_solver-0.9.27}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multi-puzzle-solver
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.27
|
|
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
|
|
@@ -331,6 +331,16 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
|
331
331
|
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/palisade_solved.png" alt="Palisade" width="140">
|
|
332
332
|
</a>
|
|
333
333
|
</td>
|
|
334
|
+
<td align="center">
|
|
335
|
+
<a href="#flip-puzzle-type-44"><b>Flip</b><br><br>
|
|
336
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/flip_unsolved.png" alt="Flip" width="140">
|
|
337
|
+
</a>
|
|
338
|
+
</td>
|
|
339
|
+
<td align="center">
|
|
340
|
+
<a href="#nurikabe-puzzle-type-45"><b>Nurikabe</b><br><br>
|
|
341
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/nurikabe_unsolved.png" alt="Nurikabe" width="140">
|
|
342
|
+
</a>
|
|
343
|
+
</td>
|
|
334
344
|
</tr>
|
|
335
345
|
</table>
|
|
336
346
|
|
|
@@ -389,6 +399,8 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
|
389
399
|
- [Binairo (Puzzle Type #41)](#binairo-puzzle-type-41)
|
|
390
400
|
- [Rectangles (Puzzle Type #42)](#rectangles-puzzle-type-42)
|
|
391
401
|
- [Palisade (Puzzle Type #43)](#palisade-puzzle-type-43)
|
|
402
|
+
- [Flip (Puzzle Type #44)](#flip-puzzle-type-44)
|
|
403
|
+
- [Nurikabe (Puzzle Type #45)](#nurikabe-puzzle-type-45)
|
|
392
404
|
- [Why SAT / CP-SAT?](#why-sat--cp-sat)
|
|
393
405
|
- [Testing](#testing)
|
|
394
406
|
- [Contributing](#contributing)
|
|
@@ -3730,14 +3742,13 @@ Applying the solution to the puzzle visually:
|
|
|
3730
3742
|
|
|
3731
3743
|
---
|
|
3732
3744
|
|
|
3733
|
-
|
|
3734
3745
|
## Palisade (Puzzle Type #43)
|
|
3735
3746
|
|
|
3736
3747
|
* [**Play online**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/palisade.html)
|
|
3737
3748
|
|
|
3738
3749
|
* [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/palisade.html#palisade)
|
|
3739
3750
|
|
|
3740
|
-
* [**Solver Code**][
|
|
3751
|
+
* [**Solver Code**][43]
|
|
3741
3752
|
|
|
3742
3753
|
<details>
|
|
3743
3754
|
<summary><strong>Rules</strong></summary>
|
|
@@ -3819,6 +3830,189 @@ Applying the solution to the puzzle visually:
|
|
|
3819
3830
|
|
|
3820
3831
|
---
|
|
3821
3832
|
|
|
3833
|
+
## Flip (Puzzle Type #44)
|
|
3834
|
+
|
|
3835
|
+
* [**Play online**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/flip.html)
|
|
3836
|
+
|
|
3837
|
+
* [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/flip.html#flip)
|
|
3838
|
+
|
|
3839
|
+
* [**Solver Code**][44]
|
|
3840
|
+
|
|
3841
|
+
<details>
|
|
3842
|
+
<summary><strong>Rules</strong></summary>
|
|
3843
|
+
|
|
3844
|
+
You have a grid of squares, some light and some dark. Your aim is to light all the squares up at the same time. You can choose any square and flip its state from light to dark or dark to light, but when you do so, other squares around it change state as well.
|
|
3845
|
+
|
|
3846
|
+
</details>
|
|
3847
|
+
|
|
3848
|
+
**Unsolved puzzle**
|
|
3849
|
+
|
|
3850
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/flip_unsolved.png" alt="Flip unsolved" width="500">
|
|
3851
|
+
|
|
3852
|
+
Code to utilize this package and solve the puzzle:
|
|
3853
|
+
|
|
3854
|
+
(Note: the solver also supports random mapping of squares to the neighbors they flip, see the test cases in `tests/test_flip.py` for usage examples)
|
|
3855
|
+
|
|
3856
|
+
```python
|
|
3857
|
+
import numpy as np
|
|
3858
|
+
from puzzle_solver import flip_solver as solver
|
|
3859
|
+
board = np.array([
|
|
3860
|
+
['B', 'W', 'W', 'W', 'W', 'W', 'W'],
|
|
3861
|
+
['B', 'B', 'W', 'W', 'W', 'B', 'B'],
|
|
3862
|
+
['W', 'B', 'W', 'W', 'B', 'B', 'W'],
|
|
3863
|
+
['B', 'B', 'B', 'W', 'W', 'B', 'W'],
|
|
3864
|
+
['W', 'W', 'B', 'B', 'W', 'B', 'W'],
|
|
3865
|
+
['B', 'W', 'B', 'B', 'W', 'W', 'W'],
|
|
3866
|
+
['B', 'W', 'B', 'W', 'W', 'B', 'B'],
|
|
3867
|
+
])
|
|
3868
|
+
binst = solver.Board(board=board)
|
|
3869
|
+
solutions = binst.solve_and_print()
|
|
3870
|
+
```
|
|
3871
|
+
|
|
3872
|
+
**Script Output**
|
|
3873
|
+
|
|
3874
|
+
The output tells you which squares to tap to solve the puzzle.
|
|
3875
|
+
|
|
3876
|
+
```python
|
|
3877
|
+
Solution found
|
|
3878
|
+
[['T' ' ' 'T' 'T' 'T' ' ' ' ']
|
|
3879
|
+
[' ' ' ' ' ' 'T' ' ' 'T' ' ']
|
|
3880
|
+
[' ' 'T' ' ' ' ' 'T' ' ' ' ']
|
|
3881
|
+
['T' ' ' 'T' ' ' ' ' 'T' ' ']
|
|
3882
|
+
[' ' ' ' ' ' 'T' ' ' ' ' 'T']
|
|
3883
|
+
['T' ' ' 'T' ' ' 'T' 'T' 'T']
|
|
3884
|
+
[' ' ' ' ' ' ' ' ' ' 'T' 'T']]
|
|
3885
|
+
Solutions found: 1
|
|
3886
|
+
status: OPTIMAL
|
|
3887
|
+
```
|
|
3888
|
+
|
|
3889
|
+
**Solved puzzle**
|
|
3890
|
+
|
|
3891
|
+
This picture won't mean much as the game is about the sequence of moves not the final frame as shown here.
|
|
3892
|
+
|
|
3893
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/flip_solved.png" alt="Flip solved" width="500">
|
|
3894
|
+
|
|
3895
|
+
---
|
|
3896
|
+
## Nurikabe (Puzzle Type #45)
|
|
3897
|
+
|
|
3898
|
+
* [**Play online**](https://www.puzzle-nurikabe.com/)
|
|
3899
|
+
|
|
3900
|
+
* [**Instructions**](https://www.logicgamesonline.com/nurikabe/)
|
|
3901
|
+
|
|
3902
|
+
* [**Solver Code**][45]
|
|
3903
|
+
|
|
3904
|
+
<details>
|
|
3905
|
+
<summary><strong>Rules</strong></summary>
|
|
3906
|
+
|
|
3907
|
+
Nurikabe is a binary determination puzzle. You must decide for each cell if it is white or black according to the following rules:
|
|
3908
|
+
|
|
3909
|
+
- All of the black cells must be connected.
|
|
3910
|
+
- Each numbered cell must be part of a white island of connected white cells.
|
|
3911
|
+
- Each island must have the same number of white cells as the number it contains (including the numbered cell).
|
|
3912
|
+
- Two islands may not be connected.
|
|
3913
|
+
- There cannot be any 2x2 blocks of black cells.
|
|
3914
|
+
|
|
3915
|
+
Read more about the history and methods behind nurikabe in the [Wikipedia nurikabe article](https://en.wikipedia.org/wiki/Nurikabe).
|
|
3916
|
+
|
|
3917
|
+
</details>
|
|
3918
|
+
|
|
3919
|
+
**Unsolved puzzle**
|
|
3920
|
+
|
|
3921
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/nurikabe_unsolved.png" alt="Nurikabe unsolved" width="500">
|
|
3922
|
+
|
|
3923
|
+
Code to utilize this package and solve the puzzle:
|
|
3924
|
+
|
|
3925
|
+
(Note: the solver also supports random mapping of squares to the neighbors they flip, see the test cases in `tests/test_flip.py` for usage examples)
|
|
3926
|
+
|
|
3927
|
+
```python
|
|
3928
|
+
import numpy as np
|
|
3929
|
+
from puzzle_solver import nurikabe_solver as solver
|
|
3930
|
+
board = np.array([
|
|
3931
|
+
['2', ' ', '3', ' ', '3', ' ', ' ', ' ', '3', ' ', ' ', '3', ' ', ' ', ' ', '2', ' ', '2', ' ', ' '],
|
|
3932
|
+
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
|
|
3933
|
+
[' ', ' ', ' ', ' ', '2', ' ', ' ', '1', ' ', ' ', '1', ' ', '3', ' ', ' ', ' ', '3', ' ', ' ', ' '],
|
|
3934
|
+
['2', ' ', ' ', '1', ' ', ' ', '3', ' ', ' ', '2', ' ', '2', ' ', ' ', ' ', '1', ' ', ' ', ' ', ' '],
|
|
3935
|
+
[' ', ' ', '2', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', ' '],
|
|
3936
|
+
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
|
|
3937
|
+
['1', ' ', ' ', ' ', ' ', '1', ' ', '2', ' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', '2'],
|
|
3938
|
+
[' ', '2', ' ', '2', ' ', ' ', '1', ' ', ' ', ' ', ' ', ' ', ' ', '6', ' ', ' ', '2', ' ', ' ', ' '],
|
|
3939
|
+
[' ', ' ', ' ', ' ', ' ', '2', ' ', '7', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '3', ' '],
|
|
3940
|
+
[' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', '2', ' ', '2', ' ', ' ', ' ', ' ', ' '],
|
|
3941
|
+
['4', ' ', ' ', ' ', ' ', ' ', '7', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
|
|
3942
|
+
[' ', ' ', ' ', ' ', '7', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', ' ', ' '],
|
|
3943
|
+
[' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', '1', ' ', ' ', ' ', ' ', ' ', '3'],
|
|
3944
|
+
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' ', '4', ' ', ' ', '7', ' ', ' ', ' ', ' '],
|
|
3945
|
+
[' ', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
|
|
3946
|
+
[' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', ' '],
|
|
3947
|
+
['2', ' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', '3', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', ' '],
|
|
3948
|
+
[' ', ' ', ' ', '4', ' ', ' ', ' ', ' ', '1', ' ', ' ', ' ', '2', ' ', '1', ' ', '3', ' ', ' ', ' '],
|
|
3949
|
+
[' ', '1', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2'],
|
|
3950
|
+
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '1', ' ', ' ', ' ', ' ', ' '],
|
|
3951
|
+
])
|
|
3952
|
+
binst = solver.Board(board=board)
|
|
3953
|
+
solutions = binst.solve_and_print()
|
|
3954
|
+
```
|
|
3955
|
+
|
|
3956
|
+
**Script Output**
|
|
3957
|
+
|
|
3958
|
+
The output tells you which squares to tap to solve the puzzle.
|
|
3959
|
+
|
|
3960
|
+
```python
|
|
3961
|
+
Solution found
|
|
3962
|
+
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
|
|
3963
|
+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
|
|
3964
|
+
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
|
3965
|
+
0│ 2 │▒▒▒│ 3 │▒▒▒│ 3 │ │ │▒▒▒│ 3 │ │▒▒▒│ 3 │ │ │▒▒▒│ 2 │▒▒▒│ 2 │ │▒▒▒│
|
|
3966
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3967
|
+
1│ │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│
|
|
3968
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3969
|
+
2│▒▒▒│▒▒▒│ │▒▒▒│ 2 │ │▒▒▒│ 1 │▒▒▒│▒▒▒│ 1 │▒▒▒│ 3 │ │▒▒▒│▒▒▒│ 3 │ │ │▒▒▒│
|
|
3970
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3971
|
+
3│ 2 │▒▒▒│▒▒▒│ 1 │▒▒▒│▒▒▒│ 3 │▒▒▒│▒▒▒│ 2 │▒▒▒│ 2 │▒▒▒│ │▒▒▒│ 1 │▒▒▒│▒▒▒│▒▒▒│▒▒▒│
|
|
3972
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3973
|
+
4│ │▒▒▒│ 2 │▒▒▒│ 2 │▒▒▒│ │ │▒▒▒│ │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 3 │ │ │▒▒▒│
|
|
3974
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3975
|
+
5│▒▒▒│▒▒▒│ │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 2 │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│
|
|
3976
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3977
|
+
6│ 1 │▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 1 │▒▒▒│ 2 │ │▒▒▒│ 3 │▒▒▒│ │▒▒▒│ │ │▒▒▒│ 1 │▒▒▒│ 2 │
|
|
3978
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3979
|
+
7│▒▒▒│ 2 │▒▒▒│ 2 │▒▒▒│▒▒▒│ 1 │▒▒▒│▒▒▒│▒▒▒│ │ │▒▒▒│ 6 │ │▒▒▒│ 2 │▒▒▒│▒▒▒│ │
|
|
3980
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3981
|
+
8│▒▒▒│ │▒▒▒│ │▒▒▒│ 2 │▒▒▒│ 7 │ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│ │▒▒▒│ 3 │▒▒▒│
|
|
3982
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3983
|
+
9│▒▒▒│▒▒▒│ 3 │▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│ │▒▒▒│ 2 │▒▒▒│ 2 │▒▒▒│ 2 │▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│
|
|
3984
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3985
|
+
10│ 4 │▒▒▒│ │ │▒▒▒│▒▒▒│ 7 │▒▒▒│ │▒▒▒│ │▒▒▒│ │▒▒▒│ │▒▒▒│ │▒▒▒│ │▒▒▒│
|
|
3986
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3987
|
+
11│ │▒▒▒│▒▒▒│▒▒▒│ 7 │▒▒▒│ │▒▒▒│ │ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 3 │ │▒▒▒│▒▒▒│▒▒▒│
|
|
3988
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3989
|
+
12│ │▒▒▒│ 2 │▒▒▒│ │▒▒▒│ │▒▒▒│▒▒▒│ │▒▒▒│ 1 │▒▒▒│ 1 │▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│ 3 │
|
|
3990
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3991
|
+
13│ │▒▒▒│ │▒▒▒│ │▒▒▒│ │ │▒▒▒│▒▒▒│ 2 │▒▒▒│ 4 │▒▒▒│▒▒▒│ 7 │ │ │▒▒▒│ │
|
|
3992
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3993
|
+
14│▒▒▒│ 1 │▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│ │ │▒▒▒│ │▒▒▒│ │ │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│ │
|
|
3994
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3995
|
+
15│▒▒▒│▒▒▒│ 2 │▒▒▒│ │ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│ │▒▒▒│ 1 │▒▒▒│▒▒▒│
|
|
3996
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3997
|
+
16│ 2 │▒▒▒│ │▒▒▒│▒▒▒│ │▒▒▒│ 1 │▒▒▒│ 3 │ │ │▒▒▒│▒▒▒│▒▒▒│ │▒▒▒│▒▒▒│ 2 │ │
|
|
3998
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
3999
|
+
17│ │▒▒▒│▒▒▒│ 4 │▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 1 │▒▒▒│▒▒▒│▒▒▒│ 2 │▒▒▒│ 1 │▒▒▒│ 3 │▒▒▒│▒▒▒│▒▒▒│
|
|
4000
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
4001
|
+
18│▒▒▒│ 1 │▒▒▒│ │ │ │▒▒▒│ 3 │▒▒▒│▒▒▒│ 1 │▒▒▒│ │▒▒▒│▒▒▒│▒▒▒│ │ │▒▒▒│ 2 │
|
|
4002
|
+
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
|
4003
|
+
19│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │ │▒▒▒│▒▒▒│▒▒▒│▒▒▒│▒▒▒│ 1 │▒▒▒│▒▒▒│▒▒▒│▒▒▒│ │
|
|
4004
|
+
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
|
4005
|
+
Solutions found: 1
|
|
4006
|
+
status: OPTIMAL
|
|
4007
|
+
Time taken: 1.62 seconds
|
|
4008
|
+
```
|
|
4009
|
+
|
|
4010
|
+
**Solved puzzle**
|
|
4011
|
+
|
|
4012
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/nurikabe_solved.png" alt="Nurikabe solved" width="500">
|
|
4013
|
+
|
|
4014
|
+
---
|
|
4015
|
+
|
|
3822
4016
|
---
|
|
3823
4017
|
|
|
3824
4018
|
## Why SAT / CP-SAT?
|
|
@@ -3913,3 +4107,5 @@ Issues and PRs welcome!
|
|
|
3913
4107
|
[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
4108
|
[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
4109
|
[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"
|
|
4110
|
+
[44]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/flip "puzzle_solver/src/puzzle_solver/puzzles/flip at master · Ar-Kareem/puzzle_solver · GitHub"
|
|
4111
|
+
[45]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/nurikabe "puzzle_solver/src/puzzle_solver/puzzles/nurikabe at master · Ar-Kareem/puzzle_solver · GitHub"
|