multi-puzzle-solver 0.9.8__tar.gz → 0.9.10__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.
Files changed (79) hide show
  1. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/PKG-INFO +107 -31
  2. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/README.md +106 -30
  3. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/multi_puzzle_solver.egg-info/PKG-INFO +107 -31
  4. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/multi_puzzle_solver.egg-info/SOURCES.txt +1 -0
  5. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/__init__.py +2 -1
  6. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/star_battle/star_battle.py +16 -8
  7. multi_puzzle_solver-0.9.10/src/puzzle_solver/puzzles/star_battle/star_battle_shapeless.py +7 -0
  8. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_star_battle.py +21 -0
  9. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/pyproject.toml +0 -0
  10. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/setup.cfg +0 -0
  11. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/multi_puzzle_solver.egg-info/dependency_links.txt +0 -0
  12. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/multi_puzzle_solver.egg-info/requires.txt +0 -0
  13. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/multi_puzzle_solver.egg-info/top_level.txt +0 -0
  14. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/core/utils.py +0 -0
  15. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/core/utils_ortools.py +0 -0
  16. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/aquarium/aquarium.py +0 -0
  17. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/battleships/battleships.py +0 -0
  18. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/bridges/bridges.py +0 -0
  19. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/chess_range/chess_melee.py +0 -0
  20. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/chess_range/chess_range.py +0 -0
  21. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/chess_range/chess_solo.py +0 -0
  22. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/dominosa/dominosa.py +0 -0
  23. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/filling/filling.py +0 -0
  24. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/guess/guess.py +0 -0
  25. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/inertia/inertia.py +0 -0
  26. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/inertia/parse_map/parse_map.py +0 -0
  27. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/inertia/tsp.py +0 -0
  28. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/kakurasu/kakurasu.py +0 -0
  29. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/keen/keen.py +0 -0
  30. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/light_up/light_up.py +0 -0
  31. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/magnets/magnets.py +0 -0
  32. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/map/map.py +0 -0
  33. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/minesweeper/minesweeper.py +0 -0
  34. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/mosaic/mosaic.py +0 -0
  35. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/nonograms/nonograms.py +0 -0
  36. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/pearl/pearl.py +0 -0
  37. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/range/range.py +0 -0
  38. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/signpost/signpost.py +0 -0
  39. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/singles/singles.py +0 -0
  40. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/stitches/parse_map/parse_map.py +0 -0
  41. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/stitches/stitches.py +0 -0
  42. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/sudoku/sudoku.py +0 -0
  43. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/tents/tents.py +0 -0
  44. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/thermometers/thermometers.py +0 -0
  45. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/towers/towers.py +0 -0
  46. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/tracks/tracks.py +0 -0
  47. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/undead/undead.py +0 -0
  48. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/puzzles/unruly/unruly.py +0 -0
  49. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/src/puzzle_solver/utils/visualizer.py +0 -0
  50. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_aquarium.py +0 -0
  51. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_battleships.py +0 -0
  52. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_bridges.py +0 -0
  53. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_chess_melee.py +0 -0
  54. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_chess_range.py +0 -0
  55. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_chess_solo.py +0 -0
  56. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_dominosa.py +0 -0
  57. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_filling.py +0 -0
  58. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_guess.py +0 -0
  59. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_inertia.py +0 -0
  60. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_kakurasu.py +0 -0
  61. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_keen.py +0 -0
  62. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_light_up.py +0 -0
  63. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_magnets.py +0 -0
  64. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_map.py +0 -0
  65. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_minesweeper.py +0 -0
  66. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_mosaic.py +0 -0
  67. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_nonograms.py +0 -0
  68. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_pearl.py +0 -0
  69. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_range.py +0 -0
  70. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_signpost.py +0 -0
  71. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_singles.py +0 -0
  72. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_stitches.py +0 -0
  73. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_sudoku.py +0 -0
  74. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_tents.py +0 -0
  75. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_thermometers.py +0 -0
  76. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_towers.py +0 -0
  77. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_tracks.py +0 -0
  78. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_undead.py +0 -0
  79. {multi_puzzle_solver-0.9.8 → multi_puzzle_solver-0.9.10}/tests/test_unruly.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multi-puzzle-solver
3
- Version: 0.9.8
3
+ Version: 0.9.10
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
@@ -254,6 +254,11 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
254
254
  <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_solved.png" alt="Star Battle" width="140">
255
255
  </a>
256
256
  </td>
257
+ <td align="center">
258
+ <a href="#star-battle-shapeless-puzzle-type-32"><b>Star Battle Shapeless</b><br><br>
259
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless" width="140">
260
+ </a>
261
+ </td>
257
262
  </tr>
258
263
  </table>
259
264
 
@@ -300,6 +305,7 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
300
305
  - [Battleships (Puzzle Type #29)](#battleships-puzzle-type-29)
301
306
  - [Kakurasu (Puzzle Type #30)](#kakurasu-puzzle-type-30)
302
307
  - [Star Battle (Puzzle Type #31)](#star-battle-puzzle-type-31)
308
+ - [Star Battle Shapeless (Puzzle Type #32)](#star-battle-shapeless-puzzle-type-32)
303
309
  - [Why SAT / CP-SAT?](#why-sat--cp-sat)
304
310
  - [Testing](#testing)
305
311
  - [Contributing](#contributing)
@@ -2536,39 +2542,39 @@ Time taken: 0.00 seconds
2536
2542
 
2537
2543
  Code to utilize this package and solve the puzzle:
2538
2544
 
2539
- Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the star_count parameter depenends on the puzzle type.
2545
+ Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the `star_count` parameter depenends on the puzzle type.
2540
2546
 
2541
2547
  ```python
2542
2548
  from puzzle_solver import star_battle_solver as solver
2543
- board = np.array([
2544
- ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2545
- ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2546
- ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2547
- ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2548
- ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2549
- ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2550
- ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2551
- ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2552
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2553
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2554
- ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2555
- ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2556
- ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2557
- ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2558
- ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2559
- ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2560
- ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2561
- ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2562
- ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2563
- ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2564
- ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2565
- ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2566
- ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2567
- ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2568
- ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2569
- ])
2570
- binst = solver.Board(board=board, star_count=6)
2571
- solutions = binst.solve_and_print()
2549
+ board = np.array([
2550
+ ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2551
+ ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2552
+ ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2553
+ ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2554
+ ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2555
+ ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2556
+ ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2557
+ ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2558
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2559
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2560
+ ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2561
+ ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2562
+ ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2563
+ ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2564
+ ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2565
+ ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2566
+ ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2567
+ ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2568
+ ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2569
+ ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2570
+ ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2571
+ ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2572
+ ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2573
+ ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2574
+ ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2575
+ ])
2576
+ binst = solver.Board(board=board, star_count=6)
2577
+ solutions = binst.solve_and_print()
2572
2578
  ```
2573
2579
 
2574
2580
 
@@ -2612,6 +2618,75 @@ Time taken: 0.38 seconds
2612
2618
 
2613
2619
  ---
2614
2620
 
2621
+ ## Star Battle Shapeless (Puzzle Type #32)
2622
+
2623
+ * [**Play online**](https://www.puzzle-star-battle.com/?size=14)
2624
+
2625
+ * [**Solver Code**][32]
2626
+
2627
+ <details>
2628
+ <summary><strong>Rules</strong></summary>
2629
+
2630
+ You have to place stars on the grid according to the rules:
2631
+ - 2 stars cannot be adjacent horizontally, vertically or diagonally.
2632
+ - For 1★ puzzles, you have to place 1 star on each row and column.
2633
+ - For 2★ puzzles, the stars per row and column must be 2 etc.
2634
+ - Some places begin with a black square and cannot have stars placed on them.
2635
+
2636
+ </details>
2637
+
2638
+ **Unsolved puzzle**
2639
+
2640
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_unsolved.png" alt="Star Battle Shapeless unsolved" width="500">
2641
+
2642
+ Code to utilize this package and solve the puzzle:
2643
+
2644
+ The `star_count` parameter depenends on the puzzle type.
2645
+
2646
+ ```python
2647
+ from puzzle_solver import star_battle_shapeless_solver as shapeless_solver
2648
+ board = np.array([
2649
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2650
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2651
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' '],
2652
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2653
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2654
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2655
+ [' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'B', ' '],
2656
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', 'B', 'B', ' '],
2657
+ ['B', 'B', ' ', ' ', ' ', ' ', 'B', 'B', 'B', ' '],
2658
+ ['B', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2659
+ ])
2660
+ binst = shapeless_solver.Board(board=board, star_count=2)
2661
+ solutions = binst.solve_and_print()
2662
+ ```
2663
+
2664
+
2665
+ **Script Output**
2666
+
2667
+ ```python
2668
+ Solution found
2669
+ ['*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2670
+ [' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' '],
2671
+ [' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2672
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*'],
2673
+ [' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' ', ' '],
2674
+ ['*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' '],
2675
+ [' ', ' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' '],
2676
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
2677
+ [' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' '],
2678
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', ' ']
2679
+ Solutions found: 1
2680
+ status: OPTIMAL
2681
+ Time taken: 0.02 seconds
2682
+ ```
2683
+
2684
+ **Solved puzzle**
2685
+
2686
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless solved" width="500">
2687
+
2688
+ ---
2689
+
2615
2690
  ---
2616
2691
 
2617
2692
  ## Why SAT / CP-SAT?
@@ -2694,3 +2769,4 @@ Issues and PRs welcome!
2694
2769
  [29]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/battleships "puzzle_solver/src/puzzle_solver/puzzles/battleships at master · Ar-Kareem/puzzle_solver · GitHub"
2695
2770
  [30]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/kakurasu "puzzle_solver/src/puzzle_solver/puzzles/kakurasu at master · Ar-Kareem/puzzle_solver · GitHub"
2696
2771
  [31]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle "puzzle_solver/src/puzzle_solver/puzzles/star_battle at master · Ar-Kareem/puzzle_solver · GitHub"
2772
+ [32]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle_shapeless "puzzle_solver/src/puzzle_solver/puzzles/star_battle_shapeless at master · Ar-Kareem/puzzle_solver · GitHub"
@@ -228,6 +228,11 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
228
228
  <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_solved.png" alt="Star Battle" width="140">
229
229
  </a>
230
230
  </td>
231
+ <td align="center">
232
+ <a href="#star-battle-shapeless-puzzle-type-32"><b>Star Battle Shapeless</b><br><br>
233
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless" width="140">
234
+ </a>
235
+ </td>
231
236
  </tr>
232
237
  </table>
233
238
 
@@ -274,6 +279,7 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
274
279
  - [Battleships (Puzzle Type #29)](#battleships-puzzle-type-29)
275
280
  - [Kakurasu (Puzzle Type #30)](#kakurasu-puzzle-type-30)
276
281
  - [Star Battle (Puzzle Type #31)](#star-battle-puzzle-type-31)
282
+ - [Star Battle Shapeless (Puzzle Type #32)](#star-battle-shapeless-puzzle-type-32)
277
283
  - [Why SAT / CP-SAT?](#why-sat--cp-sat)
278
284
  - [Testing](#testing)
279
285
  - [Contributing](#contributing)
@@ -2510,39 +2516,39 @@ Time taken: 0.00 seconds
2510
2516
 
2511
2517
  Code to utilize this package and solve the puzzle:
2512
2518
 
2513
- Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the star_count parameter depenends on the puzzle type.
2519
+ Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the `star_count` parameter depenends on the puzzle type.
2514
2520
 
2515
2521
  ```python
2516
2522
  from puzzle_solver import star_battle_solver as solver
2517
- board = np.array([
2518
- ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2519
- ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2520
- ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2521
- ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2522
- ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2523
- ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2524
- ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2525
- ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2526
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2527
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2528
- ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2529
- ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2530
- ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2531
- ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2532
- ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2533
- ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2534
- ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2535
- ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2536
- ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2537
- ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2538
- ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2539
- ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2540
- ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2541
- ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2542
- ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2543
- ])
2544
- binst = solver.Board(board=board, star_count=6)
2545
- solutions = binst.solve_and_print()
2523
+ board = np.array([
2524
+ ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2525
+ ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2526
+ ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2527
+ ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2528
+ ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2529
+ ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2530
+ ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2531
+ ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2532
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2533
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2534
+ ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2535
+ ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2536
+ ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2537
+ ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2538
+ ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2539
+ ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2540
+ ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2541
+ ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2542
+ ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2543
+ ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2544
+ ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2545
+ ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2546
+ ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2547
+ ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2548
+ ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2549
+ ])
2550
+ binst = solver.Board(board=board, star_count=6)
2551
+ solutions = binst.solve_and_print()
2546
2552
  ```
2547
2553
 
2548
2554
 
@@ -2586,6 +2592,75 @@ Time taken: 0.38 seconds
2586
2592
 
2587
2593
  ---
2588
2594
 
2595
+ ## Star Battle Shapeless (Puzzle Type #32)
2596
+
2597
+ * [**Play online**](https://www.puzzle-star-battle.com/?size=14)
2598
+
2599
+ * [**Solver Code**][32]
2600
+
2601
+ <details>
2602
+ <summary><strong>Rules</strong></summary>
2603
+
2604
+ You have to place stars on the grid according to the rules:
2605
+ - 2 stars cannot be adjacent horizontally, vertically or diagonally.
2606
+ - For 1★ puzzles, you have to place 1 star on each row and column.
2607
+ - For 2★ puzzles, the stars per row and column must be 2 etc.
2608
+ - Some places begin with a black square and cannot have stars placed on them.
2609
+
2610
+ </details>
2611
+
2612
+ **Unsolved puzzle**
2613
+
2614
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_unsolved.png" alt="Star Battle Shapeless unsolved" width="500">
2615
+
2616
+ Code to utilize this package and solve the puzzle:
2617
+
2618
+ The `star_count` parameter depenends on the puzzle type.
2619
+
2620
+ ```python
2621
+ from puzzle_solver import star_battle_shapeless_solver as shapeless_solver
2622
+ board = np.array([
2623
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2624
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2625
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' '],
2626
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2627
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2628
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2629
+ [' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'B', ' '],
2630
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', 'B', 'B', ' '],
2631
+ ['B', 'B', ' ', ' ', ' ', ' ', 'B', 'B', 'B', ' '],
2632
+ ['B', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2633
+ ])
2634
+ binst = shapeless_solver.Board(board=board, star_count=2)
2635
+ solutions = binst.solve_and_print()
2636
+ ```
2637
+
2638
+
2639
+ **Script Output**
2640
+
2641
+ ```python
2642
+ Solution found
2643
+ ['*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2644
+ [' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' '],
2645
+ [' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2646
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*'],
2647
+ [' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' ', ' '],
2648
+ ['*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' '],
2649
+ [' ', ' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' '],
2650
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
2651
+ [' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' '],
2652
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', ' ']
2653
+ Solutions found: 1
2654
+ status: OPTIMAL
2655
+ Time taken: 0.02 seconds
2656
+ ```
2657
+
2658
+ **Solved puzzle**
2659
+
2660
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless solved" width="500">
2661
+
2662
+ ---
2663
+
2589
2664
  ---
2590
2665
 
2591
2666
  ## Why SAT / CP-SAT?
@@ -2668,3 +2743,4 @@ Issues and PRs welcome!
2668
2743
  [29]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/battleships "puzzle_solver/src/puzzle_solver/puzzles/battleships at master · Ar-Kareem/puzzle_solver · GitHub"
2669
2744
  [30]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/kakurasu "puzzle_solver/src/puzzle_solver/puzzles/kakurasu at master · Ar-Kareem/puzzle_solver · GitHub"
2670
2745
  [31]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle "puzzle_solver/src/puzzle_solver/puzzles/star_battle at master · Ar-Kareem/puzzle_solver · GitHub"
2746
+ [32]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle_shapeless "puzzle_solver/src/puzzle_solver/puzzles/star_battle_shapeless at master · Ar-Kareem/puzzle_solver · GitHub"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multi-puzzle-solver
3
- Version: 0.9.8
3
+ Version: 0.9.10
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
@@ -254,6 +254,11 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
254
254
  <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_solved.png" alt="Star Battle" width="140">
255
255
  </a>
256
256
  </td>
257
+ <td align="center">
258
+ <a href="#star-battle-shapeless-puzzle-type-32"><b>Star Battle Shapeless</b><br><br>
259
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless" width="140">
260
+ </a>
261
+ </td>
257
262
  </tr>
258
263
  </table>
259
264
 
@@ -300,6 +305,7 @@ These are all the puzzles that are implemented in this repo. <br> Click on any o
300
305
  - [Battleships (Puzzle Type #29)](#battleships-puzzle-type-29)
301
306
  - [Kakurasu (Puzzle Type #30)](#kakurasu-puzzle-type-30)
302
307
  - [Star Battle (Puzzle Type #31)](#star-battle-puzzle-type-31)
308
+ - [Star Battle Shapeless (Puzzle Type #32)](#star-battle-shapeless-puzzle-type-32)
303
309
  - [Why SAT / CP-SAT?](#why-sat--cp-sat)
304
310
  - [Testing](#testing)
305
311
  - [Contributing](#contributing)
@@ -2536,39 +2542,39 @@ Time taken: 0.00 seconds
2536
2542
 
2537
2543
  Code to utilize this package and solve the puzzle:
2538
2544
 
2539
- Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the star_count parameter depenends on the puzzle type.
2545
+ Note that as usual the board is an id of the shape (id is meaningless, just used to identify one shape), and the `star_count` parameter depenends on the puzzle type.
2540
2546
 
2541
2547
  ```python
2542
2548
  from puzzle_solver import star_battle_solver as solver
2543
- board = np.array([
2544
- ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2545
- ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2546
- ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2547
- ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2548
- ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2549
- ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2550
- ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2551
- ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2552
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2553
- ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2554
- ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2555
- ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2556
- ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2557
- ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2558
- ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2559
- ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2560
- ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2561
- ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2562
- ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2563
- ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2564
- ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2565
- ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2566
- ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2567
- ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2568
- ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2569
- ])
2570
- binst = solver.Board(board=board, star_count=6)
2571
- solutions = binst.solve_and_print()
2549
+ board = np.array([
2550
+ ['00', '00', '00', '00', '00', '01', '01', '01', '01', '01', '01', '01', '01', '01', '02', '02', '02', '03', '03', '03', '03', '03', '03', '03', '03'],
2551
+ ['00', '01', '00', '01', '01', '01', '01', '01', '01', '01', '04', '04', '01', '02', '02', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03'],
2552
+ ['00', '01', '01', '01', '01', '01', '01', '01', '01', '04', '04', '04', '04', '04', '02', '02', '05', '05', '05', '05', '05', '05', '03', '03', '03'],
2553
+ ['00', '01', '06', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '04', '02', '05', '05', '05', '05', '05', '05', '05', '03', '07', '03'],
2554
+ ['00', '01', '06', '06', '06', '06', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '05', '07', '03'],
2555
+ ['00', '00', '08', '06', '09', '09', '09', '09', '06', '04', '04', '04', '04', '02', '02', '02', '02', '02', '05', '05', '05', '05', '07', '07', '07'],
2556
+ ['00', '08', '08', '08', '08', '09', '09', '06', '06', '06', '04', '04', '04', '04', '02', '02', '02', '05', '05', '05', '07', '07', '07', '07', '07'],
2557
+ ['00', '00', '08', '08', '08', '09', '09', '09', '09', '06', '10', '10', '10', '10', '02', '02', '02', '05', '11', '11', '11', '11', '07', '07', '07'],
2558
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '09', '10', '10', '10', '02', '02', '02', '02', '11', '11', '11', '11', '11', '11', '07', '11'],
2559
+ ['08', '08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '02', '02', '02', '11', '11', '11', '11', '11', '11', '11', '07', '11'],
2560
+ ['08', '08', '08', '09', '09', '09', '09', '09', '10', '10', '10', '10', '10', '12', '12', '12', '12', '11', '11', '11', '11', '11', '11', '11', '11'],
2561
+ ['08', '08', '09', '09', '09', '09', '09', '08', '10', '10', '10', '10', '10', '10', '10', '10', '12', '11', '11', '11', '11', '13', '11', '13', '11'],
2562
+ ['14', '08', '08', '08', '08', '08', '08', '08', '10', '10', '10', '10', '10', '12', '12', '12', '12', '12', '11', '11', '11', '13', '11', '13', '15'],
2563
+ ['14', '14', '14', '14', '16', '08', '16', '16', '17', '10', '10', '10', '10', '10', '10', '10', '10', '12', '13', '13', '13', '13', '13', '13', '15'],
2564
+ ['14', '14', '14', '14', '16', '16', '16', '16', '17', '10', '10', '18', '18', '10', '19', '10', '12', '12', '13', '15', '15', '15', '15', '15', '15'],
2565
+ ['14', '14', '14', '14', '14', '16', '16', '17', '17', '18', '18', '18', '19', '19', '19', '10', '10', '10', '13', '15', '15', '15', '15', '15', '15'],
2566
+ ['14', '14', '14', '16', '16', '16', '16', '17', '18', '18', '20', '20', '19', '21', '19', '19', '19', '19', '13', '15', '15', '15', '15', '15', '15'],
2567
+ ['14', '16', '16', '16', '16', '16', '16', '17', '18', '18', '20', '21', '21', '21', '21', '19', '21', '19', '15', '15', '21', '15', '15', '15', '15'],
2568
+ ['14', '14', '14', '16', '16', '17', '17', '17', '18', '20', '20', '21', '20', '21', '21', '19', '21', '19', '15', '21', '21', '15', '15', '15', '15'],
2569
+ ['14', '14', '14', '16', '16', '16', '17', '17', '18', '18', '20', '20', '20', '20', '21', '21', '21', '21', '21', '21', '15', '15', '22', '22', '15'],
2570
+ ['14', '14', '14', '14', '23', '16', '17', '20', '18', '20', '20', '20', '20', '20', '20', '21', '24', '24', '24', '21', '15', '15', '22', '15', '15'],
2571
+ ['14', '14', '14', '14', '23', '20', '17', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '21', '15', '22', '22', '22', '15'],
2572
+ ['14', '23', '23', '14', '23', '20', '20', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '22', '15'],
2573
+ ['14', '23', '14', '14', '23', '20', '23', '20', '18', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '22', '22', '22', '22', '22'],
2574
+ ['14', '23', '23', '23', '23', '23', '23', '20', '20', '20', '20', '20', '20', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24', '24']
2575
+ ])
2576
+ binst = solver.Board(board=board, star_count=6)
2577
+ solutions = binst.solve_and_print()
2572
2578
  ```
2573
2579
 
2574
2580
 
@@ -2612,6 +2618,75 @@ Time taken: 0.38 seconds
2612
2618
 
2613
2619
  ---
2614
2620
 
2621
+ ## Star Battle Shapeless (Puzzle Type #32)
2622
+
2623
+ * [**Play online**](https://www.puzzle-star-battle.com/?size=14)
2624
+
2625
+ * [**Solver Code**][32]
2626
+
2627
+ <details>
2628
+ <summary><strong>Rules</strong></summary>
2629
+
2630
+ You have to place stars on the grid according to the rules:
2631
+ - 2 stars cannot be adjacent horizontally, vertically or diagonally.
2632
+ - For 1★ puzzles, you have to place 1 star on each row and column.
2633
+ - For 2★ puzzles, the stars per row and column must be 2 etc.
2634
+ - Some places begin with a black square and cannot have stars placed on them.
2635
+
2636
+ </details>
2637
+
2638
+ **Unsolved puzzle**
2639
+
2640
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_unsolved.png" alt="Star Battle Shapeless unsolved" width="500">
2641
+
2642
+ Code to utilize this package and solve the puzzle:
2643
+
2644
+ The `star_count` parameter depenends on the puzzle type.
2645
+
2646
+ ```python
2647
+ from puzzle_solver import star_battle_shapeless_solver as shapeless_solver
2648
+ board = np.array([
2649
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2650
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2651
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' '],
2652
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2653
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2654
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2655
+ [' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'B', ' '],
2656
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', 'B', 'B', ' '],
2657
+ ['B', 'B', ' ', ' ', ' ', ' ', 'B', 'B', 'B', ' '],
2658
+ ['B', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
2659
+ ])
2660
+ binst = shapeless_solver.Board(board=board, star_count=2)
2661
+ solutions = binst.solve_and_print()
2662
+ ```
2663
+
2664
+
2665
+ **Script Output**
2666
+
2667
+ ```python
2668
+ Solution found
2669
+ ['*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2670
+ [' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' '],
2671
+ [' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' ', ' '],
2672
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*'],
2673
+ [' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' ', ' '],
2674
+ ['*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' '],
2675
+ [' ', ' ', ' ', '*', ' ', ' ', '*', ' ', ' ', ' '],
2676
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
2677
+ [' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', ' '],
2678
+ [' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', ' ']
2679
+ Solutions found: 1
2680
+ status: OPTIMAL
2681
+ Time taken: 0.02 seconds
2682
+ ```
2683
+
2684
+ **Solved puzzle**
2685
+
2686
+ <img src="https://raw.githubusercontent.com/Ar-Kareem/puzzle_solver/master/images/star_battle_shapeless_solved.png" alt="Star Battle Shapeless solved" width="500">
2687
+
2688
+ ---
2689
+
2615
2690
  ---
2616
2691
 
2617
2692
  ## Why SAT / CP-SAT?
@@ -2694,3 +2769,4 @@ Issues and PRs welcome!
2694
2769
  [29]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/battleships "puzzle_solver/src/puzzle_solver/puzzles/battleships at master · Ar-Kareem/puzzle_solver · GitHub"
2695
2770
  [30]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/kakurasu "puzzle_solver/src/puzzle_solver/puzzles/kakurasu at master · Ar-Kareem/puzzle_solver · GitHub"
2696
2771
  [31]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle "puzzle_solver/src/puzzle_solver/puzzles/star_battle at master · Ar-Kareem/puzzle_solver · GitHub"
2772
+ [32]: https://github.com/Ar-Kareem/puzzle_solver/tree/master/src/puzzle_solver/puzzles/star_battle_shapeless "puzzle_solver/src/puzzle_solver/puzzles/star_battle_shapeless at master · Ar-Kareem/puzzle_solver · GitHub"
@@ -33,6 +33,7 @@ src/puzzle_solver/puzzles/range/range.py
33
33
  src/puzzle_solver/puzzles/signpost/signpost.py
34
34
  src/puzzle_solver/puzzles/singles/singles.py
35
35
  src/puzzle_solver/puzzles/star_battle/star_battle.py
36
+ src/puzzle_solver/puzzles/star_battle/star_battle_shapeless.py
36
37
  src/puzzle_solver/puzzles/stitches/stitches.py
37
38
  src/puzzle_solver/puzzles/stitches/parse_map/parse_map.py
38
39
  src/puzzle_solver/puzzles/sudoku/sudoku.py
@@ -21,6 +21,7 @@ from puzzle_solver.puzzles.range import range as range_solver
21
21
  from puzzle_solver.puzzles.signpost import signpost as signpost_solver
22
22
  from puzzle_solver.puzzles.singles import singles as singles_solver
23
23
  from puzzle_solver.puzzles.star_battle import star_battle as star_battle_solver
24
+ from puzzle_solver.puzzles.star_battle import star_battle_shapeless as star_battle_shapeless_solver
24
25
  from puzzle_solver.puzzles.stitches import stitches as stitches_solver
25
26
  from puzzle_solver.puzzles.sudoku import sudoku as sudoku_solver
26
27
  from puzzle_solver.puzzles.tents import tents as tents_solver
@@ -32,4 +33,4 @@ from puzzle_solver.puzzles.unruly import unruly as unruly_solver
32
33
 
33
34
  from puzzle_solver.puzzles.inertia.parse_map.parse_map import main as inertia_image_parser
34
35
 
35
- __version__ = '0.9.8'
36
+ __version__ = '0.9.10'
@@ -6,19 +6,22 @@ from puzzle_solver.core.utils_ortools import generic_solve_all, SingleSolution
6
6
 
7
7
 
8
8
  class Board:
9
- def __init__(self, board: np.array, star_count: int = 1):
9
+ def __init__(self, board: np.array, star_count: int = 1, shapeless: bool = False):
10
10
  assert board.ndim == 2, f'board must be 2d, got {board.ndim}'
11
11
  assert board.shape[0] == board.shape[1], 'board must be square'
12
12
  assert star_count >= 1 and isinstance(star_count, int), 'star_count must be an integer greater than or equal to 1'
13
- assert all((str(c.item()).isdecimal() for c in np.nditer(board))), 'board must contain only digits'
14
13
  self.board = board
15
14
  self.V = board.shape[0]
16
15
  self.H = board.shape[1]
17
16
  self.N = self.V * self.H
18
17
  self.star_count = star_count
19
- self.block_numbers = set([int(c.item()) for c in np.nditer(board)])
20
- self.blocks = {i: [pos for pos in get_all_pos(self.V, self.H) if int(get_char(self.board, pos)) == i] for i in self.block_numbers}
21
-
18
+ self.shapeless = shapeless
19
+ if not shapeless:
20
+ assert all((str(c.item()).isdecimal() for c in np.nditer(board))), 'board must contain only digits'
21
+ self.block_numbers = set([int(c.item()) for c in np.nditer(board)])
22
+ self.blocks = {i: [pos for pos in get_all_pos(self.V, self.H) if int(get_char(self.board, pos)) == i] for i in self.block_numbers}
23
+ else:
24
+ assert all((str(c.item()) in [' ', 'B'] for c in np.nditer(board))), 'board must contain only digits'
22
25
  self.model = cp_model.CpModel()
23
26
  self.model_vars: dict[Pos, cp_model.IntVar] = {}
24
27
 
@@ -30,13 +33,18 @@ class Board:
30
33
  self.model_vars[pos] = self.model.NewBoolVar(f'{pos}')
31
34
 
32
35
  def add_all_constraints(self):
33
- # N stars per row / column / block
36
+ # N stars per row / column
34
37
  for row in range(self.V):
35
38
  self.model.Add(sum(self.model_vars[pos] for pos in get_row_pos(row, H=self.H)) == self.star_count)
36
39
  for col in range(self.H):
37
40
  self.model.Add(sum(self.model_vars[pos] for pos in get_col_pos(col, V=self.V)) == self.star_count)
38
- for block_i in self.block_numbers:
39
- self.model.Add(sum(self.model_vars[pos] for pos in self.blocks[block_i]) == self.star_count)
41
+ if self.shapeless: # shapeless version = no blocks but disallow black cells
42
+ for pos in get_all_pos(self.V, self.H):
43
+ if get_char(self.board, pos) == 'B':
44
+ self.model.Add(self.model_vars[pos] == 0)
45
+ else: # shaped version = blocks
46
+ for block_i in self.block_numbers:
47
+ self.model.Add(sum(self.model_vars[pos] for pos in self.blocks[block_i]) == self.star_count)
40
48
  # stars cant be adjacent
41
49
  for pos in get_all_pos(self.V, self.H):
42
50
  for neighbor in get_neighbors8(pos, V=self.V, H=self.H):
@@ -0,0 +1,7 @@
1
+ import numpy as np
2
+
3
+ from . import star_battle
4
+
5
+ class Board(star_battle.Board):
6
+ def __init__(self, board: np.array, star_count: int = 1):
7
+ super().__init__(board=board, star_count=star_count, shapeless=True)
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from puzzle_solver import star_battle_solver as solver
4
+ from puzzle_solver import star_battle_shapeless_solver as shapeless_solver
4
5
  from puzzle_solver.core.utils import get_pos
5
6
 
6
7
 
@@ -94,6 +95,26 @@ def test_ground_2():
94
95
  for pos in solution.keys():
95
96
  assert solution[pos] == ground_assignment[pos], f'solution[{pos}] != ground_assignment[{pos}], {solution[pos]} != {ground_assignment[pos]}'
96
97
 
98
+ def test_ground_3():
99
+ # https://www.puzzle-star-battle.com/?e=MTQ6OSw4ODEsNTc1
100
+ board = np.array([
101
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
102
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
103
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'B', ' '],
104
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
105
+ ['B', 'B', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
106
+ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
107
+ [' ', ' ', ' ', ' ', 'B', ' ', ' ', ' ', 'B', ' '],
108
+ ['B', ' ', ' ', ' ', ' ', ' ', ' ', 'B', 'B', ' '],
109
+ ['B', 'B', ' ', ' ', ' ', ' ', 'B', 'B', 'B', ' '],
110
+ ['B', ' ', ' ', ' ', 'B', ' ', ' ', ' ', ' ', ' '],
111
+ ])
112
+ binst = shapeless_solver.Board(board=board, star_count=2)
113
+ solutions = binst.solve_and_print()
114
+ assert len(solutions) == 1, f'unique solutions != 1, == {len(solutions)}'
115
+ solution = solutions[0].assignment
116
+
117
+
97
118
  if __name__ == '__main__':
98
119
  test_ground_1()
99
120
  test_ground_2()