#[derive(Clone, Debug)] pub struct StoneWall { rows: Vec>, } #[allow(clippy::option_map_unit_fn)] impl StoneWall { #[allow(dead_code)] pub fn create_empty(n: u32) -> Self { let n = n as usize; let h = n / 2 + 1; let mut rows = vec![vec![0; n]; h]; rows.get_mut(0).map(|r| r[0] = 1); // Should be rewitten to express rows.get_mut(1).map(|r| r[1] = 2); // its purpose more clearly Self { rows } } #[allow(dead_code)] pub fn set_stone(&mut self, row: u32, pos: u32, stone: u32) -> Option<()> { self.rows .get_mut(row as usize) .and_then(|v| v.get_mut(pos as usize)) .map(|v| *v = stone) } #[allow(dead_code)] pub fn output(&mut self) { let colors = [[31, 32], [33, 35]]; //self.rows.sort_by_key(|x| x[0]); for (i, row) in self.rows.iter().enumerate() { for (j, &stone) in row.iter().enumerate() { //print!("{}", colors[i & 1][j & 1]); print!( "\x1b[{}m{}", colors[i & 1][j & 1], "◙".repeat(stone as usize) ); } println!("\x1b[m"); } } } pub struct GapHeights { heights: Vec, } impl GapHeights { #[allow(dead_code)] pub fn from_heights(heights: Vec) -> Self { Self { heights } } #[allow(dead_code)] 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 } } #[allow(dead_code)] pub fn add_gap(&mut self, height: u32) { self.heights.push(height) } #[allow(dead_code)] 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; } } #[allow(dead_code)] pub fn output(&self, n: u32, h: u32) { let mut stones = vec![0; n as usize]; let mut colors = [ "\x1b[31m", "\x1b[32m", "\x1b[33m", "\x1b[34m", "\x1b[35m", "\x1b[36m", ] .iter() .cycle(); let mut indices = Vec::with_capacity(h as usize); for i in 0..n { let n = self.heights[i as usize]; if indices.iter().all(|x| *x != n) { indices.push(n); } } //println!("{:?} : {:?}", indices, self.heights); for row in indices { self.calculate_row(row, &mut stones); for &len in stones.iter() { print!("{}", colors.next().unwrap()); for _ in 0..len { print!("◙"); } } println!("\x1b[m"); } } #[allow(dead_code)] pub fn iter(&self) -> GapIter { GapIter { gap_heights: self, i: 0, } } #[allow(dead_code)] pub fn as_stone_wall(&self, n: u32) -> StoneWall { let h = n / 2 + 1; let mut rows = Vec::with_capacity(h as usize); for i in 0..h { let mut row = vec![0; n as usize]; self.calculate_row(i, &mut row); rows.push(row); } StoneWall { rows } } } pub struct GapIter<'a> { gap_heights: &'a GapHeights, i: usize, } impl<'a> Iterator for GapIter<'a> { type Item = u32; fn next(&mut self) -> Option { let i = self.i; self.i += 1; self.gap_heights.heights.get(i).cloned() } }