Add test: Hidato.
hidato_wikipedia: 4 guesses.
This commit is contained in:
parent
abb4cebce3
commit
d9f92e2baa
111
tests/hidato.rs
Normal file
111
tests/hidato.rs
Normal file
@ -0,0 +1,111 @@
|
||||
//! Hidato.
|
||||
//!
|
||||
//! https://en.wikipedia.org/wiki/Hidato
|
||||
|
||||
extern crate puzzle_solver;
|
||||
|
||||
use puzzle_solver::{Puzzle,Solution,Val,VarToken};
|
||||
|
||||
const WIDTH: usize = 8;
|
||||
const HEIGHT: usize = 8;
|
||||
const NA: i32 = -1;
|
||||
type Board = [[i32; WIDTH]; HEIGHT];
|
||||
|
||||
fn make_hidato(board: &Board) -> (Puzzle, Vec<VarToken>) {
|
||||
let mut sys = Puzzle::new();
|
||||
let mut pos = Vec::new();
|
||||
let mut count = 0;
|
||||
|
||||
for y in 0..HEIGHT {
|
||||
for x in 0..WIDTH {
|
||||
if board[y][x] != NA {
|
||||
pos.push((WIDTH * y + x) as Val);
|
||||
count = count + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let vars = sys.new_vars_with_candidates_1d(count, &pos);
|
||||
|
||||
for y in 0..HEIGHT {
|
||||
for x in 0..WIDTH {
|
||||
if board[y][x] > 0 {
|
||||
let idx = (board[y][x] - 1) as usize;
|
||||
sys.set_value(vars[idx], (WIDTH * y + x) as Val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sys.all_different(&vars);
|
||||
|
||||
let stride = WIDTH as Val;
|
||||
let deltas = [
|
||||
-stride - 1, -stride, -stride + 1,
|
||||
-1, 1,
|
||||
stride - 1, stride, stride + 1 ];
|
||||
|
||||
for i in 1..vars.len() {
|
||||
let step = sys.new_var_with_candidates(&deltas);
|
||||
sys.equals(vars[i], vars[i - 1] + step);
|
||||
}
|
||||
|
||||
(sys, vars)
|
||||
}
|
||||
|
||||
fn print_hidato(dict: &Solution, vars: &Vec<VarToken>) {
|
||||
let mut board = [[NA; WIDTH]; HEIGHT];
|
||||
|
||||
for (idx, &var) in vars.iter().enumerate() {
|
||||
let x = (dict[var] as usize) % WIDTH;
|
||||
let y = (dict[var] as usize) / WIDTH;
|
||||
board[y][x] = (idx as i32) + 1;
|
||||
}
|
||||
|
||||
for y in 0..HEIGHT {
|
||||
for x in 0..WIDTH {
|
||||
if board[y][x] == NA {
|
||||
print!(" --");
|
||||
} else {
|
||||
print!(" {:2}", board[y][x]);
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_hidato(dict: &Solution, vars: &Vec<VarToken>, expected: &Board) {
|
||||
for (idx, &var) in vars.iter().enumerate() {
|
||||
let x = (dict[var] as usize) % WIDTH;
|
||||
let y = (dict[var] as usize) / WIDTH;
|
||||
assert_eq!((idx as i32) + 1, expected[y][x]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hidato_wikipedia() {
|
||||
let puzzle = [
|
||||
[ 0, 33, 35, 0, 0, NA, NA, NA ],
|
||||
[ 0, 0, 24, 22, 0, NA, NA, NA ],
|
||||
[ 0, 0, 0, 21, 0, 0, NA, NA ],
|
||||
[ 0, 26, 0, 13, 40, 11, NA, NA ],
|
||||
[ 27, 0, 0, 0, 9, 0, 1, NA ],
|
||||
[ NA, NA, 0, 0, 18, 0, 0, NA ],
|
||||
[ NA, NA, NA, NA, 0, 7, 0, 0 ],
|
||||
[ NA, NA, NA, NA, NA, NA, 5, 0 ] ];
|
||||
|
||||
let expected = [
|
||||
[ 32, 33, 35, 36, 37, NA, NA, NA ],
|
||||
[ 31, 34, 24, 22, 38, NA, NA, NA ],
|
||||
[ 30, 25, 23, 21, 12, 39, NA, NA ],
|
||||
[ 29, 26, 20, 13, 40, 11, NA, NA ],
|
||||
[ 27, 28, 14, 19, 9, 10, 1, NA ],
|
||||
[ NA, NA, 15, 16, 18, 8, 2, NA ],
|
||||
[ NA, NA, NA, NA, 17, 7, 6, 3 ],
|
||||
[ NA, NA, NA, NA, NA, NA, 5, 4 ] ];
|
||||
|
||||
let (mut sys, vars) = make_hidato(&puzzle);
|
||||
let dict = sys.solve_any().expect("solution");
|
||||
print_hidato(&dict, &vars);
|
||||
verify_hidato(&dict, &vars, &expected);
|
||||
println!("hidato_wikipedia: {} guesses", sys.num_guesses());
|
||||
}
|
Loading…
Reference in New Issue
Block a user