multi-puzzle-solver 0.9.18__tar.gz → 0.9.20__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.18/src/multi_puzzle_solver.egg-info → multi_puzzle_solver-0.9.20}/PKG-INFO +218 -1
- multi_puzzle_solver-0.9.18/PKG-INFO → multi_puzzle_solver-0.9.20/README.md +3451 -3260
- multi_puzzle_solver-0.9.18/README.md → multi_puzzle_solver-0.9.20/src/multi_puzzle_solver.egg-info/PKG-INFO +3477 -3234
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/multi_puzzle_solver.egg-info/SOURCES.txt +4 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/__init__.py +3 -1
- multi_puzzle_solver-0.9.20/src/puzzle_solver/puzzles/norinori/norinori.py +101 -0
- multi_puzzle_solver-0.9.20/src/puzzle_solver/puzzles/slitherlink/slitherlink.py +248 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/stitches/parse_map/parse_map.py +36 -3
- multi_puzzle_solver-0.9.20/tests/test_norinori.py +204 -0
- multi_puzzle_solver-0.9.20/tests/test_slitherlink.py +68 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/pyproject.toml +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/setup.cfg +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/multi_puzzle_solver.egg-info/dependency_links.txt +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/multi_puzzle_solver.egg-info/requires.txt +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/multi_puzzle_solver.egg-info/top_level.txt +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/core/utils.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/core/utils_ortools.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/aquarium/aquarium.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/battleships/battleships.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/black_box/black_box.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/bridges/bridges.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/chess_range/chess_melee.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/chess_range/chess_range.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/chess_range/chess_solo.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/dominosa/dominosa.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/filling/filling.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/galaxies/galaxies.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/galaxies/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/guess/guess.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/inertia/inertia.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/inertia/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/inertia/tsp.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/kakurasu/kakurasu.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/keen/keen.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/light_up/light_up.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/lits/lits.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/magnets/magnets.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/map/map.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/minesweeper/minesweeper.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/mosaic/mosaic.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/nonograms/nonograms.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/pearl/pearl.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/range/range.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/signpost/signpost.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/singles/singles.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/slant/parse_map/parse_map.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/slant/slant.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/star_battle/star_battle.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/star_battle/star_battle_shapeless.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/stitches/stitches.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/sudoku/sudoku.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/tents/tents.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/thermometers/thermometers.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/towers/towers.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/tracks/tracks.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/undead/undead.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/unequal/unequal.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/puzzles/unruly/unruly.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/src/puzzle_solver/utils/visualizer.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_aquarium.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_battleships.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_black_box.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_bridges.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_chess_melee.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_chess_range.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_chess_solo.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_dominosa.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_filling.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_galaxies.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_guess.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_inertia.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_kakurasu.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_keen.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_light_up.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_lits.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_magnets.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_map.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_minesweeper.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_mosaic.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_nonograms.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_pearl.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_range.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_signpost.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_singles.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_slant.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_star_battle.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_stitches.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_sudoku.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_tents.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_thermometers.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_towers.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_tracks.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_undead.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_unequal.py +0 -0
- {multi_puzzle_solver-0.9.18 → multi_puzzle_solver-0.9.20}/tests/test_unruly.py +0 -0
{multi_puzzle_solver-0.9.18/src/multi_puzzle_solver.egg-info → multi_puzzle_solver-0.9.20}/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.20
|
|
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
|
|
@@ -299,6 +299,16 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
|
299
299
|
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/unequal_solved.png" alt="Unequal" width="140">
|
|
300
300
|
</a>
|
|
301
301
|
</td>
|
|
302
|
+
<td align="center">
|
|
303
|
+
<a href="#norinori-puzzle-type-38"><b>Norinori</b><br><br>
|
|
304
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/norinori_solved.png" alt="Norinori" width="140">
|
|
305
|
+
</a>
|
|
306
|
+
</td>
|
|
307
|
+
<td align="center">
|
|
308
|
+
<a href="#slitherlink-puzzle-type-39"><b>Slitherlink</b><br><br>
|
|
309
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/slitherlink_solved.png" alt="Slitherlink" width="140">
|
|
310
|
+
</a>
|
|
311
|
+
</td>
|
|
302
312
|
</tr>
|
|
303
313
|
</table>
|
|
304
314
|
|
|
@@ -351,6 +361,8 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
|
|
|
351
361
|
- [Galaxies (Puzzle Type #35)](#galaxies-puzzle-type-35)
|
|
352
362
|
- [Slant (Puzzle Type #36)](#slant-puzzle-type-36)
|
|
353
363
|
- [Unequal (Puzzle Type #37)](#unequal-puzzle-type-37)
|
|
364
|
+
- [Norinori (Puzzle Type #38)](#norinori-puzzle-type-38)
|
|
365
|
+
- [Slitherlink (Puzzle Type #39)](#slitherlink-puzzle-type-39)
|
|
354
366
|
- [Why SAT / CP-SAT?](#why-sat--cp-sat)
|
|
355
367
|
- [Testing](#testing)
|
|
356
368
|
- [Contributing](#contributing)
|
|
@@ -3083,6 +3095,8 @@ Applying the solution to the puzzle visually:
|
|
|
3083
3095
|
|
|
3084
3096
|
## Unequal (Puzzle Type #37)
|
|
3085
3097
|
|
|
3098
|
+
Also called "Futoshiki" or Renzoku"
|
|
3099
|
+
|
|
3086
3100
|
* [**Play online**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/unequal.html)
|
|
3087
3101
|
|
|
3088
3102
|
* [**Instructions**](https://www.chiark.greenend.org.uk/~sgtatham/puzzles/doc/unequal.html#unequal)
|
|
@@ -3117,6 +3131,7 @@ Code to utilize this package and solve the puzzle:
|
|
|
3117
3131
|
Note: For an NxM board you need an (2N-1)x(2M-1) array because the puzzle involves input in between the cells. Each numbered cell has neighbors horizontally to represent ">", "<", and "|" (where "|" represents adjacency) and vertically to represent "∧", "∨" and "-" (where "-" represents adjacency). The "X" in the input are unused corners that shouldnt contain anything (just a corner). The numbers should never appear orthogonal to an "X", only diagonally to it. vice-versa for the comparison operators.
|
|
3118
3132
|
|
|
3119
3133
|
```python
|
|
3134
|
+
from puzzle_solver import unequal_solver as solver
|
|
3120
3135
|
board = np.array([
|
|
3121
3136
|
[' ', ' ', ' ', ' ', '9', ' ', '1', ' ', '7', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', '>', ' '],
|
|
3122
3137
|
[' ', 'X', 'V', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', '∧', 'X', ' ', 'X', ' ', 'X', ' '],
|
|
@@ -3170,6 +3185,206 @@ Applying the solution to the puzzle visually:
|
|
|
3170
3185
|
|
|
3171
3186
|
---
|
|
3172
3187
|
|
|
3188
|
+
## Norinori (Puzzle Type #38)
|
|
3189
|
+
|
|
3190
|
+
* [**Play online**](https://www.puzzle-norinori.com)
|
|
3191
|
+
|
|
3192
|
+
* [**Solver Code**][38]
|
|
3193
|
+
|
|
3194
|
+
<details>
|
|
3195
|
+
<summary><strong>Rules</strong></summary>
|
|
3196
|
+
|
|
3197
|
+
You have to shade some of the cells in such a way that:
|
|
3198
|
+
- Exactly 2 cells are shaded in each region.
|
|
3199
|
+
- Each shaded cell should be a part of a domino*. Dominoes can cross the region borders.
|
|
3200
|
+
- The dominoes cannot touch each other except diagonally.
|
|
3201
|
+
|
|
3202
|
+
* A domino is a shape made of 2 shaded cells next to each other (1x2 or 2x1).
|
|
3203
|
+
|
|
3204
|
+
</details>
|
|
3205
|
+
|
|
3206
|
+
**Unsolved puzzle**
|
|
3207
|
+
|
|
3208
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/norinori_unsolved.png" alt="Norinori unsolved" width="500">
|
|
3209
|
+
|
|
3210
|
+
Code to utilize this package and solve the puzzle:
|
|
3211
|
+
|
|
3212
|
+
```python
|
|
3213
|
+
from puzzle_solver import norinori_solver as solver
|
|
3214
|
+
board = np.array([
|
|
3215
|
+
['00', '01', '01', '01', '01', '02', '03', '03', '04', '04', '04', '05', '05', '05', '06', '07', '08', '08', '09', '09'],
|
|
3216
|
+
['00', '00', '01', '01', '01', '02', '03', '04', '04', '10', '11', '11', '05', '06', '06', '07', '08', '08', '12', '12'],
|
|
3217
|
+
['13', '13', '13', '01', '01', '03', '03', '10', '10', '10', '11', '14', '05', '14', '07', '07', '07', '12', '12', '12'],
|
|
3218
|
+
['13', '15', '13', '16', '16', '16', '17', '17', '17', '18', '18', '14', '14', '14', '07', '07', '07', '07', '07', '12'],
|
|
3219
|
+
['13', '15', '15', '16', '19', '19', '17', '17', '17', '18', '18', '18', '14', '20', '07', '07', '21', '21', '21', '21'],
|
|
3220
|
+
['13', '19', '19', '19', '19', '19', '17', '22', '22', '22', '22', '18', '14', '20', '20', '07', '21', '23', '23', '21'],
|
|
3221
|
+
['24', '24', '25', '25', '25', '25', '26', '27', '27', '27', '28', '28', '20', '20', '29', '29', '30', '30', '31', '31'],
|
|
3222
|
+
['24', '24', '25', '32', '33', '33', '26', '27', '27', '34', '28', '35', '35', '36', '36', '29', '37', '30', '31', '31'],
|
|
3223
|
+
['38', '32', '32', '32', '33', '27', '27', '27', '27', '34', '28', '28', '35', '35', '29', '29', '37', '37', '31', '37'],
|
|
3224
|
+
['38', '38', '32', '39', '33', '40', '34', '34', '34', '34', '28', '35', '35', '35', '41', '37', '37', '37', '37', '37'],
|
|
3225
|
+
['42', '38', '39', '39', '40', '40', '43', '43', '34', '44', '28', '35', '45', '45', '41', '41', '41', '41', '46', '46'],
|
|
3226
|
+
['42', '42', '39', '47', '47', '40', '40', '44', '44', '44', '48', '48', '48', '48', '48', '41', '49', '49', '49', '46'],
|
|
3227
|
+
['50', '50', '39', '39', '40', '40', '40', '40', '51', '51', '51', '52', '48', '48', '53', '41', '54', '54', '49', '46'],
|
|
3228
|
+
['50', '39', '39', '55', '55', '40', '40', '40', '56', '51', '51', '52', '53', '48', '53', '41', '41', '54', '49', '46'],
|
|
3229
|
+
['39', '39', '39', '57', '56', '56', '56', '56', '56', '56', '53', '53', '53', '53', '53', '58', '58', '58', '59', '59'],
|
|
3230
|
+
['60', '39', '39', '57', '57', '61', '61', '61', '62', '56', '56', '63', '63', '63', '63', '63', '59', '59', '59', '59'],
|
|
3231
|
+
['60', '64', '65', '65', '61', '61', '66', '66', '62', '62', '62', '67', '63', '63', '68', '69', '69', '69', '69', '69'],
|
|
3232
|
+
['60', '64', '65', '65', '65', '65', '66', '70', '70', '70', '70', '67', '67', '71', '68', '69', '72', '73', '73', '69'],
|
|
3233
|
+
['60', '60', '60', '65', '66', '66', '66', '66', '74', '75', '75', '75', '67', '71', '68', '68', '72', '73', '73', '73'],
|
|
3234
|
+
['76', '76', '76', '76', '76', '77', '77', '74', '74', '74', '74', '67', '67', '71', '71', '71', '72', '73', '78', '78']
|
|
3235
|
+
])
|
|
3236
|
+
binst = solver.Board(board=board)
|
|
3237
|
+
solutions = binst.solve_and_print()
|
|
3238
|
+
```
|
|
3239
|
+
**Script Output**
|
|
3240
|
+
|
|
3241
|
+
```python
|
|
3242
|
+
Solution found
|
|
3243
|
+
[
|
|
3244
|
+
[ 'X', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', 'X' ],
|
|
3245
|
+
[ 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ' ],
|
|
3246
|
+
[ ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', 'X', ' ', ' ', ' ', 'X', ' ', ' ' ],
|
|
3247
|
+
[ 'X', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X' ],
|
|
3248
|
+
[ ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X', 'X', ' ', ' ', 'X' ],
|
|
3249
|
+
[ ' ', 'X', ' ', ' ', 'X', ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X', 'X', ' ' ],
|
|
3250
|
+
[ ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X' ],
|
|
3251
|
+
[ 'X', ' ', 'X', 'X', ' ', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', 'X', ' ', ' ', 'X', ' ', 'X' ],
|
|
3252
|
+
[ 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ' ],
|
|
3253
|
+
[ ' ', 'X', 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', 'X', 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', ' ' ],
|
|
3254
|
+
[ 'X', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', 'X', ' ', ' ', 'X', 'X', ' ', ' ', ' ', 'X', 'X', ' ' ],
|
|
3255
|
+
[ 'X', ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', 'X', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ' ],
|
|
3256
|
+
[ ' ', 'X', 'X', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', 'X' ],
|
|
3257
|
+
[ 'X', ' ', ' ', 'X', 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ' ],
|
|
3258
|
+
[ 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', ' ', 'X', ' ', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ' ],
|
|
3259
|
+
[ ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X', 'X', ' ', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', 'X' ],
|
|
3260
|
+
[ ' ', 'X', ' ', ' ', ' ', 'X', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', 'X' ],
|
|
3261
|
+
[ ' ', 'X', ' ', 'X', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', 'X', 'X', ' ', ' ', ' ', 'X', 'X', ' ' ],
|
|
3262
|
+
[ 'X', ' ', 'X', ' ', ' ', ' ', ' ', 'X', ' ', ' ', 'X', 'X', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ' ],
|
|
3263
|
+
[ 'X', ' ', 'X', ' ', ' ', 'X', 'X', ' ', 'X', 'X', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', 'X', 'X' ],
|
|
3264
|
+
]
|
|
3265
|
+
Solutions found: 1
|
|
3266
|
+
status: OPTIMAL
|
|
3267
|
+
Time taken: 0.04 seconds
|
|
3268
|
+
```
|
|
3269
|
+
|
|
3270
|
+
**Solved puzzle**
|
|
3271
|
+
|
|
3272
|
+
Applying the solution to the puzzle visually:
|
|
3273
|
+
|
|
3274
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/norinori_solved.png" alt="Norinori solved" width="500">
|
|
3275
|
+
|
|
3276
|
+
---
|
|
3277
|
+
|
|
3278
|
+
## Slitherlink (Puzzle Type #39)
|
|
3279
|
+
|
|
3280
|
+
Also known as Fences and Loop the Loop
|
|
3281
|
+
|
|
3282
|
+
* [**Play online**](https://www.puzzle-loop.com)
|
|
3283
|
+
|
|
3284
|
+
* [**Solver Code**][39]
|
|
3285
|
+
|
|
3286
|
+
<details>
|
|
3287
|
+
<summary><strong>Rules</strong></summary>
|
|
3288
|
+
|
|
3289
|
+
You have to draw lines between the dots to form a single loop without crossings or branches. The numbers indicate how many lines surround it.
|
|
3290
|
+
|
|
3291
|
+
A line forming a single loop without crossings or branches means that every corner has either 2 or 0 lines touching it.
|
|
3292
|
+
|
|
3293
|
+
</details>
|
|
3294
|
+
|
|
3295
|
+
**Unsolved puzzle**
|
|
3296
|
+
|
|
3297
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/slitherlink_unsolved.png" alt="Slitherlink unsolved" width="500">
|
|
3298
|
+
|
|
3299
|
+
Code to utilize this package and solve the puzzle:
|
|
3300
|
+
|
|
3301
|
+
```python
|
|
3302
|
+
from puzzle_solver import slitherlink_solver as solver
|
|
3303
|
+
board = np.array([
|
|
3304
|
+
['3', ' ', ' ', '2', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', '3', ' ', ' ', '1', ' '],
|
|
3305
|
+
[' ', ' ', '3', ' ', '3', ' ', ' ', ' ', '3', ' ', '2', '2', ' ', '2', ' ', '2', '2', ' ', '2', '3'],
|
|
3306
|
+
['2', '2', ' ', ' ', ' ', '2', '1', ' ', '1', '1', ' ', ' ', '3', '1', ' ', '2', ' ', ' ', ' ', '2'],
|
|
3307
|
+
[' ', ' ', '2', ' ', ' ', '2', '2', ' ', ' ', ' ', '3', ' ', ' ', ' ', ' ', ' ', '2', '2', '3', ' '],
|
|
3308
|
+
['1', '2', '1', ' ', ' ', ' ', '2', '1', ' ', '3', '2', ' ', '3', '2', '2', '3', ' ', '3', '2', '2'],
|
|
3309
|
+
[' ', '3', '2', '2', '1', '2', ' ', '3', ' ', ' ', ' ', ' ', '2', '2', '3', ' ', '1', '1', ' ', '2'],
|
|
3310
|
+
['1', ' ', ' ', ' ', ' ', ' ', '2', ' ', ' ', '2', ' ', '1', '3', ' ', ' ', ' ', ' ', '2', '2', '2'],
|
|
3311
|
+
[' ', '3', ' ', '2', '0', '1', '2', '1', ' ', '1', '3', ' ', '2', ' ', ' ', '2', ' ', '2', '1', ' '],
|
|
3312
|
+
['2', ' ', ' ', ' ', '2', ' ', '3', ' ', ' ', ' ', ' ', '2', ' ', ' ', '1', '2', ' ', ' ', '1', '3'],
|
|
3313
|
+
[' ', ' ', '1', ' ', ' ', ' ', ' ', '2', '0', ' ', '1', ' ', '2', ' ', '0', ' ', '2', ' ', '3', '2'],
|
|
3314
|
+
[' ', '3', ' ', '3', ' ', '1', '3', ' ', '3', ' ', '2', ' ', ' ', '2', '2', '2', '3', ' ', ' ', ' '],
|
|
3315
|
+
['3', ' ', ' ', ' ', ' ', ' ', ' ', '0', '2', '1', ' ', ' ', '2', ' ', ' ', '1', ' ', '0', '2', ' '],
|
|
3316
|
+
[' ', ' ', ' ', ' ', ' ', ' ', '3', ' ', '3', '2', '3', ' ', ' ', '2', ' ', '1', ' ', ' ', ' ', ' '],
|
|
3317
|
+
['2', '2', ' ', '3', '0', ' ', ' ', '3', ' ', ' ', '2', ' ', ' ', ' ', ' ', '2', '2', ' ', '3', ' '],
|
|
3318
|
+
[' ', '2', '0', ' ', ' ', '3', ' ', '1', ' ', ' ', '2', ' ', '2', '2', ' ', ' ', ' ', '2', ' ', '2'],
|
|
3319
|
+
[' ', ' ', '1', '3', '1', ' ', ' ', ' ', ' ', ' ', '2', ' ', '2', '1', ' ', '1', '2', '2', ' ', ' '],
|
|
3320
|
+
['2', ' ', '2', '2', ' ', '1', '3', ' ', '2', ' ', '3', '1', '2', ' ', '3', '2', ' ', '1', '1', ' '],
|
|
3321
|
+
[' ', ' ', '2', ' ', '1', ' ', ' ', ' ', '2', ' ', ' ', ' ', '2', ' ', '1', '0', ' ', ' ', ' ', '3'],
|
|
3322
|
+
[' ', '2', ' ', ' ', '2', ' ', '2', '3', '2', ' ', '2', '2', ' ', '3', '2', '2', '3', '3', '1', ' '],
|
|
3323
|
+
['0', '0', ' ', '3', '2', ' ', ' ', ' ', ' ', ' ', '2', '1', '2', '1', ' ', ' ', ' ', '2', '1', ' '],
|
|
3324
|
+
])
|
|
3325
|
+
binst = solver.Board(board=board)
|
|
3326
|
+
solutions = binst.solve_and_print()
|
|
3327
|
+
```
|
|
3328
|
+
**Script Output**
|
|
3329
|
+
|
|
3330
|
+
```python
|
|
3331
|
+
Solution found
|
|
3332
|
+
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
|
|
3333
|
+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
|
|
3334
|
+
┌───┐ ┌───────┐ ┌───────────────────┐ ┌───────┐ ┌───┐ ┌───────────┐
|
|
3335
|
+
0│ 3 │ · │ · 2 │ · │ · · · · 3 │ · · │ · · │ · │ 3 │ · │ · 1 · │
|
|
3336
|
+
│ │ └───┐ │ │ ┌───────┐ ┌───┘ ┌───┘ ┌───┘ │ │ └───┐ ┌───┘
|
|
3337
|
+
1│ · │ · 3 │ · │ 3 │ · │ · · │ 3 │ · 2 │ 2 · │ 2 · │ 2 │ 2 · │ 2 │ 3
|
|
3338
|
+
│ │ ┌───┘ └───┘ │ └───┘ ┌───┘ ┌───┘ │ └───────┘ └───┐
|
|
3339
|
+
2│ 2 │ 2 │ · · · 2 │ 1 · 1 1 │ · · │ 3 1 · │ 2 · · · 2 │
|
|
3340
|
+
│ │ │ ┌───────────┘ ┌───┐ └───┐ └───────┐ └───────┐ ┌───┐ │
|
|
3341
|
+
3│ · │ · │ 2 │ · · 2 2 │ · │ · · 3 │ · · · │ · · 2 │ 2 │ 3 │ · │
|
|
3342
|
+
│ └───┘ └───────────────┘ └───┐ ┌───┘ ┌───┐ │ ┌───┐ │ │ │ │
|
|
3343
|
+
4│ 1 2 1 · · · 2 1 · │ 3 │ 2 · │ 3 │ 2 │ 2 │ 3 │ · │ 3 │ 2 │ 2 │
|
|
3344
|
+
│ ┌───────────────────────────┐ └───┘ ┌───┘ │ │ │ │ └───┘ │ │
|
|
3345
|
+
5│ · │ 3 2 2 1 2 · 3 │ · · · │ · 2 │ 2 │ 3 │ · │ 1 1 · │ 2 │
|
|
3346
|
+
│ └───────────┐ ┌───────────┘ ┌───────┘ ┌───┘ └───┘ │ ┌───┘ │
|
|
3347
|
+
6│ 1 · · · │ · │ · 2 · · │ 2 · 1 │ 3 · · · │ · 2 │ 2 2 │
|
|
3348
|
+
│ ┌───────────┘ └───────────────┘ ┌───┐ └───────────┐ └───────┘ ┌───┘
|
|
3349
|
+
7│ · │ 3 · 2 0 1 2 1 · 1 │ 3 │ · 2 · · │ 2 · 2 1 │ ·
|
|
3350
|
+
│ └───┐ ┌───┐ ┌───┐ ┌───┐ │ └───────────┐ └───┐ ┌───┐ └───┐
|
|
3351
|
+
8│ 2 · │ · │ · │ 2 · │ 3 │ · │ · │ · │ · 2 · · │ 1 2 │ · │ · │ 1 3 │
|
|
3352
|
+
└───┐ └───┘ └───┐ │ └───┘ └───┘ ┌───┐ ┌───┘ └───┘ │ ┌───┘
|
|
3353
|
+
9 · │ · 1 · · │ · │ · 2 0 · 1 │ · │ 2 │ · 0 · 2 · │ 3 │ 2
|
|
3354
|
+
└───┐ ┌───────┘ │ ┌───┐ ┌───┐ │ │ │ ┌───────┐ └───┘
|
|
3355
|
+
10 · 3 │ · │ 3 · 1 │ 3 │ · │ 3 │ · │ 2 │ · │ · │ 2 2 │ 2 3 │ · · ·
|
|
3356
|
+
┌───────┘ └───────┐ └───┘ └───┘ │ │ │ └───────┘ ┌───┘ ┌───┐
|
|
3357
|
+
11│ 3 · · · · │ · · 0 2 1 │ · │ · │ 2 · · 1 │ · 0 2 │ · │
|
|
3358
|
+
└───┐ ┌───────┐ │ ┌───┐ ┌───┐ │ │ └───┐ ┌───┐ └───┐ ┌───┘ │
|
|
3359
|
+
12 · │ · │ · · │ · │ · │ 3 │ · │ 3 │ 2 │ 3 │ · · │ 2 │ · │ 1 · │ · │ · · │
|
|
3360
|
+
┌───┘ │ ┌───┘ └───┘ │ │ │ └───┘ ┌───┘ │ │ ┌───┘ └───┐ │
|
|
3361
|
+
13│ 2 2 │ · │ 3 0 · · │ 3 │ · │ · 2 · │ · · │ · │ 2 │ 2 · 3 │ · │
|
|
3362
|
+
│ ┌───┘ └───┐ ┌───┐ └───┘ └───────────┘ ┌───┘ │ │ ┌───────┘ │
|
|
3363
|
+
14│ · │ 2 0 · │ · │ 3 │ · 1 · · 2 · 2 │ 2 · │ · │ · │ 2 · 2 │
|
|
3364
|
+
│ │ ┌───┘ │ │ ┌───────────────────┘ └───┘ │ ┌───────┘
|
|
3365
|
+
15│ · │ · 1 │ 3 1 │ · │ · · │ · · 2 · 2 1 · 1 2 │ 2 │ · ·
|
|
3366
|
+
│ └───┐ └───┐ │ └───┐ │ ┌───────────────────┐ ┌───┘ └───────┐
|
|
3367
|
+
16│ 2 · │ 2 2 │ · │ 1 3 │ · │ 2 · │ 3 1 2 · 3 │ 2 │ · 1 1 · │
|
|
3368
|
+
└───┐ └───┐ └───┘ ┌───┘ └───┐ └───┐ ┌───────────┘ └───────┐ ┌───┘
|
|
3369
|
+
17 · │ · 2 │ · 1 · │ · · 2 │ · · │ · │ 2 · 1 0 · · │ · │ 3
|
|
3370
|
+
└───┐ └───┐ ┌───┘ ┌───┐ │ │ │ ┌───┐ ┌───┐ │ └───┐
|
|
3371
|
+
18 · 2 │ · · │ 2 │ · 2 │ 3 │ 2 │ · 2 │ 2 │ · │ 3 │ 2 2 │ 3 │ 3 │ 1 · │
|
|
3372
|
+
└───┐ │ │ ┌───┘ │ └───────┘ └───┘ └───────┘ └───┘ │
|
|
3373
|
+
19 0 0 · │ 3 │ 2 │ · │ · · │ · · 2 1 2 1 · · · 2 1 · │
|
|
3374
|
+
└───┘ └───┘ └───────────────────────────────────────────────┘
|
|
3375
|
+
Solutions found: 1
|
|
3376
|
+
status: OPTIMAL
|
|
3377
|
+
Time taken: 2.39 seconds
|
|
3378
|
+
```
|
|
3379
|
+
|
|
3380
|
+
**Solved puzzle**
|
|
3381
|
+
|
|
3382
|
+
Applying the solution to the puzzle visually:
|
|
3383
|
+
|
|
3384
|
+
<img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/slitherlink_solved.png" alt="Slitherlink solved" width="500">
|
|
3385
|
+
|
|
3386
|
+
---
|
|
3387
|
+
|
|
3173
3388
|
---
|
|
3174
3389
|
|
|
3175
3390
|
## Why SAT / CP-SAT?
|
|
@@ -3258,3 +3473,5 @@ Issues and PRs welcome!
|
|
|
3258
3473
|
[35]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/galaxies "puzzle_solver/src/puzzle_solver/puzzles/galaxies at master · Ar-Kareem/puzzle_solver · GitHub"
|
|
3259
3474
|
[36]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/slant "puzzle_solver/src/puzzle_solver/puzzles/slant at master · Ar-Kareem/puzzle_solver · GitHub"
|
|
3260
3475
|
[37]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/unequal "puzzle_solver/src/puzzle_solver/puzzles/unequal at master · Ar-Kareem/puzzle_solver · GitHub"
|
|
3476
|
+
[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"
|
|
3477
|
+
[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"
|