1mod model;
2
3use model::{compute_model, variables::create_tileset};
4
5use crate::{
6 utils::{get_n, Model},
7 DominoError, Puzzle, Solution, Tile,
8};
9
10pub fn solve_puzzle(puzzle: &Puzzle) -> Result<Solution, DominoError> {
25 let model_string = compute_model(puzzle)?;
26 let solver_result = Model::execute(model_string.clone());
29
30 let n = get_n(puzzle)?;
31 let tileset: Vec<Tile> = create_tileset(n as usize)
32 .iter()
33 .map(|tuple| Tile((*tuple).0 as i32, (*tuple).1 as i32).into())
34 .collect();
35 let tileset_digits = (tileset.len() as f32).log10().floor() as usize + 1;
36 let sequence_digits = (puzzle.0.len() as f32).log10().floor() as usize + 1;
37 if let Ok(translator) = solver_result {
38 let mut solution = puzzle.clone();
39 let variables = translator._get_variables();
40 let labels: Vec<String> = variables
41 .iter()
42 .filter_map(|entry: (&String, &f64)| {
43 if entry.1 == &1.0 {
44 Some(entry.0.clone())
45 } else {
46 None
47 }
48 })
49 .collect();
50 labels.iter().for_each(|label| {
52 let tile_index: usize = label[1..1 + tileset_digits].parse().unwrap();
53 let position_index: usize = label
54 [1 + tileset_digits..1 + tileset_digits + sequence_digits]
55 .parse()
56 .unwrap();
57 solution.0[position_index] = Some(tileset[tile_index])
58 });
59 Ok(solution.0.iter().map(|option| option.unwrap()).collect())
60 } else {
61 Err(DominoError::ModelError(
62 "Model failed execution".to_string(),
63 ))
64 }
65}