use crate::solver::{wall_stats, Solver}; use crate::structs::StoneWall; use std::iter::repeat; pub struct IncrementalBlockSover { n: u32, h: u32, w: u32, rows: Vec>, } struct SubSolver<'s> { solver: &'s mut IncrementalBlockSover, start: u32, count: u32, heights: Vec, // for all gaps the possible rows gap_possibilities: Vec>, pos: Vec, } impl<'s> SubSolver<'s> { fn from_index(solver: &'s mut IncrementalBlockSover, index: u32) -> Option { let gap_possibilities = vec![vec![]; index as usize]; let row_existence = vec![false; index as usize]; let start = solver.rows[0][index as usize].0 + 1; for row in 1..solver.h { let min_sz = start - solver.row_size(row); for gap in 0..index { if !solver.visited(row, min_sz + gap) { gap_possibilities[gap as usize].push(row); row_existence[row as usize] = true; } } } if row_existence.iter().all(|&x| x) { Some(Self { count: index, start, solver, heights: Vec::with_capacity(index as usize), pos: vec![0; gap_possibilities.len()], gap_possibilities, }) } else { None } } fn increment_at(&mut self, n: u32) -> bool { if self.pos[n as usize] as usize + 1 == self.gap_possibilities[n as usize].len() { if n as usize + 1 == self.pos.len() { false } else { self.increment_at(n + 1) } } else { self.pos[n as usize] += 1; true } } } impl<'s> Iterator for SubSolver<'s> { type Item = (); fn next(&mut self) -> Option { for (i, p) in self.pos.iter().enumerate().rev() {} None } } impl IncrementalBlockSover { fn generate_first_row(&mut self) { let mut sum = 0; self.rows[0] = (1..=self.n) .map(|n| { sum += n; (sum - n, n) }) .collect(); } fn get_wall(&self) -> StoneWall { let mut wall = StoneWall::create_empty(self.n); for (h, row) in self.rows.iter().enumerate() { for (n, &(_, stone)) in row.iter().enumerate() { wall.set_stone(h as u32, n as u32, stone).unwrap() } } wall } fn visited(&self, row: u32, stone: u32) -> bool { self.rows[row as usize] .iter() .position(|&(_, s)| s == stone) .is_some() } fn row_size(&self, row: u32) -> u32 { self.rows[row as usize].last().map_or(0, |&(i, s)| i + s) } } impl Solver for IncrementalBlockSover { fn new(n: u32) -> Self { let (h, w) = wall_stats(n); Self { n, h, w, rows: repeat(Vec::with_capacity(h as usize)) .take(h as usize) .collect(), } } fn solve(&mut self) -> StoneWall { self.generate_first_row(); println!("{:?}", self.rows); self.get_wall() } fn n(&self) -> u32 { self.n } fn h(&self) -> u32 { self.h } fn w(&self) -> u32 { self.w } }