From edaccaaf15a526714f3de4e9e044341abd037885 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 2 Jan 2020 15:34:07 +0100 Subject: Start to implement incremental block solver --- src/solvers/incremental_block.rs | 133 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/solvers/incremental_block.rs (limited to 'src/solvers/incremental_block.rs') diff --git a/src/solvers/incremental_block.rs b/src/solvers/incremental_block.rs new file mode 100644 index 0000000..d4ebb81 --- /dev/null +++ b/src/solvers/incremental_block.rs @@ -0,0 +1,133 @@ +use std::iter::repeat; +use crate::solver::{Solver, wall_stats}; +use crate::structs::StoneWall; + +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() { + t + } + 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 + } +} + -- cgit v1.2.3-54-g00ecf