From 6546a936c392c67382a135cdec8bd450485de180 Mon Sep 17 00:00:00 2001 From: David Wang Date: Fri, 24 Feb 2017 07:15:55 +1100 Subject: [PATCH] Count the number of guesses taken to solve the puzzle. --- src/puzzle.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/puzzle.rs b/src/puzzle.rs index 3904099..c430472 100644 --- a/src/puzzle.rs +++ b/src/puzzle.rs @@ -1,5 +1,6 @@ //! The puzzle's state and rules. +use std::cell::Cell; use std::collections::BTreeSet; use std::iter; use std::ops::Index; @@ -28,6 +29,9 @@ pub struct Puzzle { // The number of variables in the puzzle. num_vars: usize, + // The number of guesses to solve the puzzle. + num_guesses: Cell, + // The list of candidates for each variable. candidates: Vec, @@ -81,6 +85,7 @@ impl Puzzle { pub fn new() -> Self { Puzzle { num_vars: 0, + num_guesses: Cell::new(0), candidates: Vec::new(), constraints: Vec::new(), } @@ -309,8 +314,10 @@ impl Puzzle { /// let solution = puzzle.solve_any(); /// assert!(solution.is_some()); /// ``` - pub fn solve_any(&self) -> Option { + pub fn solve_any(&mut self) -> Option { let mut solutions = Vec::with_capacity(1); + + self.num_guesses.set(0); if self.num_vars > 0 { let mut search = PuzzleSearch::new(self); search.solve(1, &mut solutions); @@ -332,7 +339,8 @@ impl Puzzle { /// let solution = puzzle.solve_unique(); /// assert!(solution.is_none()); /// ``` - pub fn solve_unique(&self) -> Option { + pub fn solve_unique(&mut self) -> Option { + self.num_guesses.set(0); if self.num_vars > 0 { let mut search = PuzzleSearch::new(self); let mut solutions = Vec::with_capacity(2); @@ -357,8 +365,10 @@ impl Puzzle { /// let solutions = puzzle.solve_all(); /// assert_eq!(solutions.len(), 4); /// ``` - pub fn solve_all(&self) -> Vec { + pub fn solve_all(&mut self) -> Vec { let mut solutions = Vec::new(); + + self.num_guesses.set(0); if self.num_vars > 0 { let mut search = PuzzleSearch::new(self); search.solve(::std::usize::MAX, &mut solutions); @@ -373,7 +383,7 @@ impl Puzzle { /// /// Returns the intermediate puzzle search state, or None if a /// contradiction was found. - pub fn step(&self) -> Option { + pub fn step(&mut self) -> Option { if self.num_vars > 0 { let mut search = PuzzleSearch::new(self); if search.constrain() { @@ -383,6 +393,11 @@ impl Puzzle { None } + + /// Get the number of guesses taken to solve the last puzzle. + pub fn num_guesses(&self) -> u32 { + self.num_guesses.get() + } } /*--------------------------------------------------------------*/ @@ -475,6 +490,9 @@ impl<'a> PuzzleSearch<'a> { } for val in cs.iter() { + let num_guesses = self.puzzle.num_guesses.get() + 1; + self.puzzle.num_guesses.set(num_guesses); + let mut new = self.clone(); if !new.assign(idx, val) { continue; @@ -595,7 +613,7 @@ mod tests { #[test] fn test_no_vars() { - let sys = Puzzle::new(); + let mut sys = Puzzle::new(); sys.solve_any(); sys.solve_unique(); sys.solve_all();