domino_lib/functionalities/
solve.rsuse std::collections::HashSet;
use std::time::Instant;
use crate::types::error::DominoError;
use crate::types::{Puzzle, Solution, Tile};
use super::common::get_missing_tiles;
pub fn solve_puzzle(puzzle: &Puzzle) -> Result<Solution, DominoError> {
let mut new_puzzle = puzzle.clone();
let missing_tiles = get_missing_tiles(puzzle)?;
let start_instant = Instant::now();
if solve_puzzle_r(&mut new_puzzle, &missing_tiles, 0, &start_instant) {
let solution = new_puzzle.into_iter().map(|tile| tile.unwrap()).collect();
return Ok(solution);
} else {
return Err(DominoError::UnsolvablePuzzle);
}
}
fn solve_puzzle_r(puzzle: &mut Puzzle, missing_tiles: &HashSet<Tile>, current_position: usize, start_instant: &Instant) -> bool {
if current_position == puzzle.len() {
return true;
}
if puzzle[current_position].is_some() {
return solve_puzzle_r(puzzle, missing_tiles, current_position + 1, start_instant);
}
for &element in missing_tiles {
if puzzle.iter().all(|&slot| slot != Some(element)) &&
(
puzzle[(puzzle.len() + current_position - 1) % puzzle.len()].is_none() ||
puzzle[(puzzle.len() + current_position - 1) % puzzle.len()].unwrap().1 == element.0
) &&
(
puzzle[(current_position + 1) % puzzle.len()].is_none() ||
puzzle[(current_position + 1) % puzzle.len()].unwrap().0 == element.1
) {
puzzle[current_position] = Some(element);
if solve_puzzle_r(puzzle, missing_tiles, current_position + 1, start_instant) {
return true;
}
puzzle[current_position] = None;
}
element.flip();
if puzzle.iter().all(|&slot| slot != Some(element)) &&
(
puzzle[(puzzle.len() + current_position - 1) % puzzle.len()].is_none() ||
puzzle[(puzzle.len() + current_position - 1) % puzzle.len()].unwrap().1 == element.0
) &&
(
puzzle[(current_position + 1) % puzzle.len()].is_none() ||
puzzle[(current_position + 1) % puzzle.len()].unwrap().0 == element.1
) {
puzzle[current_position] = Some(element);
if solve_puzzle_r(puzzle, missing_tiles, current_position + 1, start_instant) {
return true;
}
puzzle[current_position] = None;
}
}
false
}