diff --git a/README.md b/README.md index 4757e3f..479e79c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,14 @@ About Solve logic puzzles by simply describing the puzzle's rules as constraints. This is suitable for solving puzzles with integer -variables such as Sudoku. +variables such as Sudoku, Killer Sudoku, Kakuro, and Zebra puzzles. + +The puzzle solver maintains a list of candidates for each puzzle +variable. It solves puzzles by eliminating candidates that would lead +to a contradiction and taking any forced moves that were exposed in +the process. This is repeated until it gets stuck, whereupon it will +perform a backtracking search -- it will assign a single variable and +continue with the candidate elimination step again. Examples @@ -16,8 +23,15 @@ Examples A few example programs are provided in the `tests/` directory: -* _Sudoku_ - https://en.wikipedia.org/wiki/Sudoku +* _Hidato_ - https://en.wikipedia.org/wiki/Hidato +* _Kakuro_ - https://en.wikipedia.org/wiki/Kakuro +* _Killer Sudoku_ - https://en.wikipedia.org/wiki/Killer_sudoku +* _Magic Square_ - https://en.wikipedia.org/wiki/Magic_square * _N-queens problem_ - https://en.wikipedia.org/wiki/Eight_queens_puzzle +* _Send More Money_ - https://en.wikipedia.org/wiki/Verbal_arithmetic +* _Sudoku_ - https://en.wikipedia.org/wiki/Sudoku +* _Sujiko_ - https://en.wikipedia.org/wiki/Sujiko +* _Zebra puzzle (Einstein's riddle)_ - https://en.wikipedia.org/wiki/Zebra_Puzzle To clone this repository, run: @@ -35,6 +49,7 @@ cargo test --test sudoku -- --nocapture Basic Usage ----------- +We will demonstrate how to solve the equation "SEND + MORE = MONEY". Add Puzzle Solver as a dependency to your project's Cargo.toml: ```toml @@ -42,6 +57,61 @@ Add Puzzle Solver as a dependency to your project's Cargo.toml: puzzle-solver = "0.1" ``` +Import the library in your project, e.g.: + +```rust +extern crate puzzle_solver; + +use puzzle_solver::Puzzle; +``` + +First, we create a puzzle object and the 8 puzzle variables +`(S,E,N,D,M,O,R,Y)`. + +```rust +let mut puzzle = Puzzle::new(); +let vars = puzzle.new_vars_with_candidates_1d(8, &[0,1,2,3,4,5,6,7,8,9]); +let (s, e, n, d) = (vars[0], vars[1], vars[2], vars[3]); +let (m, o, r, y) = (vars[4], vars[5], vars[6], vars[7]); +``` + +All eight puzzle variables have been initialised to be any number +between 0 and 9. However, we know that the numbers are not allowed to +begin with zero, so we remove the choices of S = 0 and M = 0. + +```rust +puzzle.remove_candidates(s, &[0]); +puzzle.remove_candidates(m, &[0]); +``` + +We add the constraint that the variables should be all different: + +```rust +puzzle.all_different(&vars); +``` + +We write the equation as another puzzle constraint: + +```rust +puzzle.equals( + (1000 * s + 100 * e + 10 * n + d) + (1000 * m + 100 * o + 10 * r + e), + 10000 * m + 1000 * o + 100 * n + 10 * e + y); +``` + +And we solve! + +```rust +let solution = puzzle.solve_any().expect("solution"); +assert_eq!(solution[o], 0); +assert_eq!(solution[m], 1); +assert_eq!(solution[y], 2); +assert_eq!(solution[e], 5); +assert_eq!(solution[n], 6); +assert_eq!(solution[d], 7); +assert_eq!(solution[r], 8); +assert_eq!(solution[s], 9); +``` + Documentation -------------