Add convenience functions for all different.

The constraint creation functions now take an IntoIterator allowing
you to use generic collections, and even perform maps and filters.
This is useful, for example, when the variables are in a 2d array.
This commit is contained in:
David Wang 2017-02-23 07:55:29 +11:00
parent fcefa40b6c
commit 3911802d89
2 changed files with 22 additions and 6 deletions

View File

@ -18,9 +18,10 @@ impl AllDifferent {
///
/// puzzle_solver::constraint::AllDifferent::new(&vars);
/// ```
pub fn new(vars: &[VarToken]) -> Self {
pub fn new<'a, I>(vars: I) -> Self
where I: IntoIterator<Item=&'a VarToken> {
AllDifferent {
vars: vars.to_vec(),
vars: vars.into_iter().map(|&x| x).collect(),
}
}
}
@ -46,7 +47,6 @@ impl Constraint for AllDifferent {
#[cfg(test)]
mod tests {
use ::{Puzzle,Val};
use super::AllDifferent;
#[test]
fn test_contradiction() {
@ -54,7 +54,7 @@ mod tests {
let v0 = puzzle.new_var_with_candidates(&[1]);
let v1 = puzzle.new_var_with_candidates(&[1]);
puzzle.add_constraint(Box::new(AllDifferent::new(&[v0,v1])));
puzzle.all_different(&[v0,v1]);
let solution = puzzle.solve_any();
assert!(solution.is_none());
@ -67,7 +67,7 @@ mod tests {
let v1 = puzzle.new_var_with_candidates(&[1,2,3]);
let v2 = puzzle.new_var_with_candidates(&[1,2,3]);
puzzle.add_constraint(Box::new(AllDifferent::new(&[v0,v1,v2])));
puzzle.all_different(&[v0,v1,v2]);
let search = puzzle.step().expect("contradiction");
assert_eq!(search[v0], 1);

View File

@ -2,11 +2,11 @@
use std::collections::BTreeSet;
use std::iter;
use std::iter::Iterator;
use std::ops::Index;
use std::rc::Rc;
use ::{Constraint,Solution,Val,VarToken};
use constraint;
/// A collection of candidates.
#[derive(Clone,Debug,Eq,PartialEq)]
@ -281,6 +281,22 @@ impl Puzzle {
self.constraints.push(constraint);
}
/// Add an All Different constraint.
///
/// # Examples
///
/// ```
/// let mut send_more_money = puzzle_solver::Puzzle::new();
/// let vars = send_more_money.new_vars_with_candidates_1d(8,
/// &[0,1,2,3,4,5,6,7,8,9]);
///
/// send_more_money.all_different(&vars);
/// ```
pub fn all_different<'a, I>(&mut self, vars: I)
where I: IntoIterator<Item=&'a VarToken> {
self.add_constraint(Box::new(constraint::AllDifferent::new(vars)));
}
/// Find any solution to the given puzzle.
///
/// # Examples