A powerful sudoku engine written in Kotlin.
Add Kudoku to your project:
dependencies {
implementation("io.github.ilikeyourhat.kudoku:kudoku:{version}")
}
Create a sudoku board providing the type and values:
val sudoku = Sudoku(
Classic9x9,
listOf(
0, 5, 7, 7, 6, 0, 0, 0, 4,
8, 0, 4, 0, 9, 5, 2, 0, 0,
0, 0, 3, 0, 0, 7, 5, 8, 1,
0, 0, 0, 7, 4, 2, 0, 1, 9,
7, 6, 1, 0, 0, 0, 8, 4, 0,
0, 2, 9, 1, 8, 0, 0, 7, 0,
1, 4, 0, 9, 0, 3, 7, 0, 0,
5, 0, 0, 6, 0, 0, 4, 9, 3,
9, 3, 0, 0, 7, 4, 0, 0, 8
)
)
...or using a string notation for improved readability:
val sudoku = Kudoku.createFromString(
"""
classic_9x9
_,5,7, 8,6,_, _,_,4
8,_,4, _,9,5, 2,_,_
_,_,3, _,_,7, 5,8,1
_,_,_, 7,4,2, _,1,9
7,6,1, _,_,_, 8,4,_
_,2,9, 1,8,_, _,7,_
1,4,_, 9,_,3, 7,_,_
5,_,_, 6,_,_, 4,9,3
9,3,_, _,7,4, _,_,8
""".trimIndent()
)
Create a solver instance and solve the board:
val solver = Kudoku.defaultSolver()
val solution = solver.solve(sudoku)
println(solution)
Choose from multiple solver implementations:
val solver1 = Kudoku.satSolver()
val solver2 = Kudoku.bruteForceSolver()
Support for popular text formats:
val string = "003020600900305001001806400008102900700000008006708200002609500800203009005010300"
val sudoku = Kudoku.createFromSingleLineString(string)
val encoded = sudoku.toSingleLineString(emptyFieldIndicator = EmptyFieldIndicator.DOT)
Create a random Sudoku with a given difficulty:
val sudoku = Kudoku.create(SudokuType.Classic9x9, Difficulty.VERY_HARD)
println(sudoku)
Check how hard is a given sudoku:
val difficulty = Kudoku.rate(sudoku) // can be EASY, MEDIUM, HARD, VERY_HARD or UNSOLVABLE
Check if a given sudoku has one solution:
val solutionCount = Kudoku.checkSolutions(sudoku) // can be ZERO, ONE or MANY
Kudoku can handle many different types of sudokus, in a reasonable time:
val samurai21x21 = Kudoku.createFromString(
"""
samurai_classic_21x21
2,_,_, _,_,8, 9,_,_, #,#,#, 9,_,_, _,3,1, _,7,8
_,_,7, _,9,_, _,_,6, #,#,#, _,3,_, _,_,5, _,_,_
3,_,_, 5,_,_, 2,_,_, #,#,#, 4,_,_, _,_,_, _,_,3
_,_,_, 8,_,_, 6,_,_, #,#,#, _,_,_, _,_,2, _,_,9
5,_,9, 1,_,_, _,_,_, #,#,#, _,7,6, _,_,_, 8,_,_
1,_,_, _,_,6, _,5,_, #,#,#, _,_,_, _,_,_, _,_,_
_,4,5, _,_,_, 3,_,_, _,_,_, _,_,7, _,_,3, _,1,_
_,1,_, _,_,_, 4,_,_, _,2,3, _,_,5, 4,_,_, _,3,_
6,_,_, _,_,_, _,_,_, _,7,_, _,_,_, _,_,6, 5,_,_
#,#,#, #,#,#, _,8,_, _,_,_, _,_,2, #,#,#, #,#,#
#,#,#, #,#,#, _,_,_, _,_,1, _,_,_, #,#,#, #,#,#
#,#,#, #,#,#, _,_,_, _,_,4, _,7,_, #,#,#, #,#,#
_,2,_, _,_,_, _,_,_, _,_,_, _,_,1, 7,_,_, _,_,_
_,_,_, _,_,_, _,_,_, _,_,_, _,_,_, _,2,9, _,5,_
9,5,_, 7,_,_, _,_,_, _,5,_, _,8,_, _,_,3, _,_,_
_,_,_, _,_,1, _,_,_, #,#,#, _,_,_, 9,_,_, _,_,_
3,4,_, _,7,_, _,_,_, #,#,#, _,_,_, _,_,_, 4,6,_
6,_,_, _,3,_, 7,_,_, #,#,#, _,9,_, _,1,_, _,8,_
_,_,_, 2,5,8, _,_,4, #,#,#, 4,2,3, _,_,_, _,_,_
_,_,3, 6,_,_, _,5,_, #,#,#, _,6,_, _,5,_, 2,_,_
4,_,_, _,_,_, 9,_,_, #,#,#, _,_,_, 3,_,_, 9,_,7
""".trimIndent()
)
val classic25x25 = Kudoku.createFromString(
"""
classic_25x25
__,__,12,06,__, __,07,__,18,__, 05,24,__,10,01, __,__,04,__,__, __,__,__,__,__
02,__,19,__,13, __,__,__,10,__, __,__,__,__,__, __,__,18,05,__, __,__,__,__,01
__,__,__,__,__, __,__,22,__,__, __,__,03,__,02, __,__,14,12,__, 16,08,25,__,__
__,16,__,__,__, 02,23,__,__,13, 12,22,__,__,__, 21,15,19,03,__, __,__,__,14,__
23,__,24,__,__, __,__,__,25,08, 04,__,16,19,21, __,__,07,__,__, __,03,12,__,09
__,04,__,02,__, __,__,__,__,__, __,10,__,24,12, 17,16,__,__,__, 05,__,__,__,__
__,__,09,__,__, 06,25,__,__,__, 08,__,05,03,__, __,__,__,__,__, 20,__,__,18,19
15,__,10,11,__, __,__,18,12,19, __,__,__,__,__, __,__,23,__,__, 07,__,__,04,__
__,__,__,__,__, __,__,14,__,22, __,__,18,16,20, __,06,11,13,__, __,__,__,__,__
__,22,__,25,__, __,01,17,05,04, 07,__,__,14,__, 08,03,21,__,__, 11,__,__,__,06
__,20,13,15,__, __,__,__,__,__, 09,__,__,02,__, 25,__,01,08,__, __,05,__,21,__
__,01,__,__,__, __,16,10,__,07, __,__,04,20,__, __,09,__,__,14, __,24,__,17,__
25,02,05,__,__, __,__,__,13,__, __,__,__,__,22, __,__,__,__,__, 19,01,08,__,__
__,__,07,21,__, __,12,__,02,17, __,__,__,18,06, 16,__,__,15,__, __,13,__,10,__
08,10,18,12,16, 09,__,__,__,05, __,__,__,__,19, __,__,17,__,21, __,15,__,__,22
__,08,__,__,15, __,03,__,06,__, 21,__,__,07,__, 18,14,05,__,01, __,__,__,__,__
__,__,__,19,__, 01,__,16,11,__, __,__,10,22,25, 15,__,__,__,__, __,__,21,__,__
__,03,01,__,21, __,__,04,__,__, __,__,02,__,13, __,24,25,__,__, 14,__,__,06,__
__,__,__,__,__, __,__,15,__,12, 14,__,06,17,24, __,__,__,__,__, __,__,13,__,__
__,05,23,16,04, __,13,24,07,02, __,09,__,__,15, 03,__,22,__,__, __,__,__,__,08
__,__,25,20,02, __,19,__,__,__, __,01,__,__,__, __,21,03,__,__, 12,__,__,__,__
16,12,__,05,__, 11,21,__,23,__, __,15,__,__,__, __,19,09,__,__, __,__,__,25,10
__,__,__,__,09, 20,22,07,04,__, 03,__,14,25,18, __,11,__,__,__, __,__,01,__,15
24,__,06,__,22, 08,__,25,14,__, 10,11,__,09,__, 20,01,16,__,07, __,23,__,__,13
14,13,21,01,__, __,05,__,__,__, 06,__,22,__,23, 10,__,__,__,02, __,__,18,07,11
""".trimIndent()
)