Akari Solver in Copris
- Top
- Akari
- Fillomino
- Hakyuu
- Hashiwokakero
- Heyawake
- Hitori
- Kakuro
- Kurodoko
- Masyu
- Nonogram
- Numberlink
- Nurikabe
- Polarium
- Shakashaka
- Shikaku
- Slitherlink
- Sokoban
- Sudoku
- Yajilin
Table of Contents
Overview
This page presents a Akari solver written in Copris, a Constraint Programming DSL (Domain-Specific Language) embedded in Scala. Akari is a puzzle game developed by Nikoli.
This Akari solver can find a solution of the given Akari puzzle.
What's New
- Release of version 2.0
- Release of version 1.1
- First release
Download
- Version 2.0
-
- Scala jar file: ../build/copris-puzzles-2.0.jar (1575981 bytes)
- Source file: ../build/copris-puzzles-src-2.0.zip (29766 bytes)
Requirements
How to use
scala -cp copris-puzzles-2.0.jar akari.Solver input_file_name
- The format of the input file is explained below.
To check the uniqueness of the solutions, please use "-o multi" option.
scala -cp copris-puzzles-2.0.jar akari.Solver -o multi input_file_name
If you have a SAT solver (such as MiniSat, GlueMiniSat) installed on your computer, you can use it to get better performance. Specify the full path of the SAT solver program with "-s1" or "-s2" option.
scala -cp copris-puzzles-2.0.jar akari.Solver -o multi -s2 minisat input_file_name
Input file format
The following is an example of input file.
10 10 1 - - - - - - - - 1 - - - x - - - - - - - x - - - 2 - - x - - - - - - - - 1 - - - - - 4 - - - - - - - - - - - - 2 - - - - - 2 - - - - - - - - x - - 2 - - - x - - - - - - - 0 - - - 1 - - - - - - - - 1
- The first line gives the number of rows.
- The second line gives the number of columns.
- Number cells are represented by its number.
- Blank cells are represented by "-".
- Black cells are represented by "x".
Example Usage
$ scala -cp copris-puzzles-2.0.jar akari.Solver -v data/001.a.txt File = data/001.a.txt Solver = Options = Rows = 10 Cols = 10 BEGIN_solution = 1 Solution = Set((7,5), (1,5), (8,9), (6,6), (9,1), (6,1), (4,4), (2,6), (0,8), (5,7), (4,2), (8,4), (5,3), (3,3), (7,2), (1,0), (3,8)) Size = 17 1 - - - - - - - @ 1 @ - - x - @ - - - - - x - - - 2 @ - x - - - - @ - - - 1 @ - - - @ 4 @ - - - - - - - - @ - - 2 @ - - - @ 2 - - - @ - - - - x @ - 2 @ - - x - - - - - @ - 0 - - @ 1 @ - - - - - - - 1 END_solution = 1 NumOfSolutions >= 1
Performance Evaluation
Solver performance is measured on version 2.0.
- Copris solver was run on Intel Xeon 3.6Hz machine with:
- Ubuntu Linux 20.04 (64 bit)
- Java version "1.8.0_275", OpenJDK Runtime Environment (with "-Xmx2G" option)
- Scala version 2.12.5
- Copris version 2.3.1
- Sugar version 2.3.4
- GlueMiniSat version 2.2.10 (with preprocessing) is used as a SAT solver.
Finding a solution
- We used 530 instances obtainded from http://www.janko.at/Raetsel/Akari/ (2013-08).
Number of instances | |
---|---|
Solved within 3600s | 530 |
Timeout | 0 |
Error (Memory Over etc.) | 0 |
Total | 530 |
Avg. CPU time | 1.9 |
Max. CPU time | 12.1 |
- See log/results.log for more details.
Source Code
The following shows the source code of the solver (Akari.scala).
1: /* 2: * Akari Solver in Copris 3: * by Naoyuki Tamura 4: * http://bach.istc.kobe-u.ac.jp/copris/puzzles/akari/ 5: */ 6: package akari 7: 8: import jp.kobe_u.copris._ 9: import jp.kobe_u.copris.dsl._ 10: import puzzle._ 11: 12: case class Akari(m: Int, n: Int, board: Seq[Seq[String]]) extends BoardPuzzle { 13: def isBlank(cell: Cell) = at(cell) == "-" 14: def isBlack(cell: Cell) = at(cell) == "x" 15: val lines = { 16: def seq(cell: Cell, dij: Cell): Seq[Cell] = 17: if (! isCell(cell) || ! isBlank(cell)) Seq.empty 18: else cell +: seq(move(cell, dij), dij) 19: val vLines = for ((i,j) <- cells; if ! isCell((i-1,j)) || ! isBlank((i-1,j))) 20: yield seq((i,j), (1,0)).toSet 21: val hLines = for ((i,j) <- cells; if ! isCell((i,j-1)) || ! isBlank((i,j-1))) 22: yield seq((i,j), (0,1)).toSet 23: vLines ++ hLines 24: } 25: def show(sol: Set[Cell]) { 26: for (i <- 0 until m) { 27: for (j <- 0 until n) { 28: val cell = (i,j) 29: if (sol.contains(cell)) print(" @") 30: else print(" " + at(cell)) 31: } 32: println 33: } 34: } 35: } 36: 37: object Solver extends BoardPuzzleSolver[Akari] { 38: val name = "akari.Solver" 39: 40: def puzzleFactory(m: Int, n: Int, board: Seq[Seq[String]]) = 41: Akari(m, n, board) 42: 43: def define = { 44: for (cell <- puzzle.cells; if puzzle.isBlank(cell)) 45: int('x(cell), 0, 1) 46: for ((cell) <- puzzle.cells; if puzzle.isNumber(cell)) { 47: val xs = puzzle.adjCells(cell, puzzle.isBlank).map('x(_)) 48: add(Add(xs) === puzzle.num(cell)) 49: } 50: val lines = puzzle.lines 51: for (k <- 0 until lines.size) { 52: int('l(k), 0, 1) 53: add('l(k) === Add(lines(k).map(cell => 'x(cell)))) 54: } 55: for (cell <- puzzle.cells; if puzzle.isBlank(cell)) { 56: val ks = (0 until lines.size).filter(k => lines(k).contains(cell)) 57: add(Or(ks.map(k => 'l(k) === 1))) 58: } 59: } 60: 61: def showSolution { 62: // Set of light cell positions 63: val sol = 64: for (cell <- puzzle.cells.toSet; if puzzle.isBlank(cell) && solution('x(cell)) > 0) 65: yield cell 66: if (quiet == 0) { 67: println("Solution = " + sol) 68: println("Size = " + sol.size) 69: puzzle.show(sol) 70: } 71: } 72: }
- It should be compiled with ../build/PuzzleSolver.scala.
License
This software is distributed under the BSD 3-Clause License. See LICENSE.
Links
- Copris (Constraint Programming DSL embedded in Scala)
- Sugar (an award winning Constraint Solver)
- Default constraint solver used in Copris
- Sat4j (SAT solver in Java)
- Default SAT solver used in Copris
- Akari (by Nikoli)
- Wikipedia:Light Up (puzzle)
- http://www.janko.at/Raetsel/Akari/