Add test: N-queens problem.

queens_4x4: 8 guesses.
queens_5x5: 21 guesses.
queens_6x6: 66 guesses.
queens_7x7: 179 guesses.
queens_8x8: 662 guesses.
This commit is contained in:
David Wang 2017-02-24 07:30:30 +11:00
parent 34e58114ea
commit 6eb25f6af0

93
tests/queens.rs Normal file
View File

@ -0,0 +1,93 @@
//! N-queens problem.
//!
//! https://en.wikipedia.org/wiki/Eight_queens_puzzle
extern crate puzzle_solver;
use puzzle_solver::{Constraint,Puzzle,PuzzleSearch,Solution,Val,VarToken};
struct NoDiagonal {
vars: Vec<VarToken>,
}
impl Constraint for NoDiagonal {
fn on_assigned(&self, search: &mut PuzzleSearch, var: VarToken, val: Val)
-> bool {
let y1 = self.vars.iter().position(|&v| v == var).expect("unreachable");
for (y2, &var2) in self.vars.iter().enumerate() {
if !search.is_assigned(var2) {
let x1 = val;
let dy = (y1 as Val) - (y2 as Val);
search.remove_candidate(var2, x1 - dy);
search.remove_candidate(var2, x1 + dy);
}
}
true
}
}
fn make_queens(n: usize) -> (Puzzle, Vec<VarToken>) {
let mut sys = Puzzle::new();
let pos: Vec<Val> = (0..n as Val).collect();
let vars = sys.new_vars_with_candidates_1d(n, &pos);
sys.all_different(&vars);
sys.add_constraint(Box::new(NoDiagonal{ vars: vars.clone() }));
(sys, vars)
}
fn print_queens(dict: &Solution, vars: &Vec<VarToken>) {
let n = vars.len() as Val;
for &var in vars.iter() {
for i in 0..n {
print!(" {}", if i == dict[var] { "Q" } else { "." });
}
println!();
}
}
#[test]
fn queens_4x4() {
let (mut sys, vars) = make_queens(4);
let dict = sys.solve_all();
assert_eq!(dict.len(), 2);
print_queens(&dict[0], &vars);
println!("queens_4x4: {} guesses", sys.num_guesses());
}
#[test]
fn queens_5x5() {
let (mut sys, vars) = make_queens(5);
let dict = sys.solve_all();
assert_eq!(dict.len(), 10);
print_queens(&dict[0], &vars);
println!("queens_5x5: {} guesses", sys.num_guesses());
}
#[test]
fn queens_6x6() {
let (mut sys, vars) = make_queens(6);
let dict = sys.solve_all();
assert_eq!(dict.len(), 4);
print_queens(&dict[0], &vars);
println!("queens_6x6: {} guesses", sys.num_guesses());
}
#[test]
fn queens_7x7() {
let (mut sys, vars) = make_queens(7);
let dict = sys.solve_all();
assert_eq!(dict.len(), 40);
print_queens(&dict[0], &vars);
println!("queens_7x7: {} guesses", sys.num_guesses());
}
#[test]
fn queens_8x8() {
let (mut sys, vars) = make_queens(8);
let dict = sys.solve_all();
assert_eq!(dict.len(), 92);
print_queens(&dict[0], &vars);
println!("queens_8x8: {} guesses", sys.num_guesses());
}