pub struct Wall { heights: Vec, } impl Wall { pub fn from_heights(heights: Vec) -> Self { Self { heights } } fn create_empty(w: u32) -> Self { let heights = if w == 0 { vec![] } else if w == 1 { vec![0] } else { let mut v = Vec::with_capacity(w as usize); v.push(0); v.push(1); v }; Self { heights } } pub fn calculate_row(&self, r: u32, stones: &mut [u32]) { let mut len = 1; let mut i = 0; for &height in self.heights.iter().chain([r].iter()) { if height == r { stones[i] = len; i += 1; len = 0; } len += 1; } } pub fn output(&self, n: u32, h: u32) { let mut stones = vec![0; n as usize]; let mut toggle = 0; let colors = [ "\x1b[31m", "\x1b[32m", "\x1b[33m", "\x1b[34m", "\x1b[35m", "\x1b[36m", ]; for row in 0..h { self.calculate_row(row, &mut stones); for &len in stones.iter() { print!("{}", colors[toggle]); toggle = (toggle + 1) % colors.len(); for _ in 0..len { print!("◙"); } } println!("\x1b[m"); } } } /// Solve for a given N and return the resulting wall pub struct Solver { pub n: u32, /// calculated height [might not be correct!] pub h: u32, /// width pub w: u32, /// Use to store already used blocks as a bitmask solve_stack: Vec>, } // used during row creation, will get deprecated static mut COUNT: u32 = 0; /// Save the current state for each row #[derive(Clone, Eq, Copy)] pub struct SaveState { /// Mask of all currently used stones pub bitmask: T, /// sum of all placed stones pub index: u32, /// the row index pub row: u32, } impl std::cmp::Ord for SaveState { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.index.cmp(&other.index) } } impl std::cmp::PartialOrd for SaveState { fn partial_cmp(&self, other: &Self) -> Option { Some(self.index.cmp(&other.index)) } } impl std::cmp::PartialEq for SaveState { fn eq(&self, other: &Self) -> bool { self.index.eq(&other.index) } } impl SaveState { pub fn new() -> Self { Self { bitmask: T::zero(), index: 0, row: unsafe { COUNT += 1; COUNT }, } } pub fn set_bit(&mut self, stone: u32) { self.bitmask = self.bitmask | T::from(1 << stone).expect("Stone placing index out of bounds"); } pub fn get_bit(&self, stone: u32) -> T { println!("{},", stone); self.bitmask & T::from(1 << stone).expect("Requested stone index out of bounds") } pub fn bridges_gap(&self, index: u32) -> bool { self.get_bit(index - self.index) == T::zero() } pub fn bridge_gap(mut self, index: u32) -> Self { self.set_bit(index - self.index); self.index = index; self } } impl Solver { pub fn new(n: u32) -> Self { let h = n / 2 + 1; let w = h * (n - 1); Self { n, h, w, solve_stack: vec![SaveState::new(); h as usize], } } //dummy solver pub fn solve(&mut self) -> Wall { let mut wall = Wall::create_empty(self.w); wall.heights .iter() .take(2) .zip(0..1) .for_each(|(x, i)| self.solve_stack[*x as usize].set_bit(i)); for i in 0..(self.n * self.h) { let machine = self .solve_stack .iter() .filter(|x| x.bridges_gap(i + 1)) .min() .unwrap() .bridge_gap(i + 1); wall.heights.push(machine.row); } wall } }