diff options
author | Dennis Kobert <dennis@kobert.dev> | 2019-12-22 13:42:31 +0100 |
---|---|---|
committer | Dennis Kobert <dennis@kobert.dev> | 2019-12-22 13:42:31 +0100 |
commit | 1c46971754b4e4247b3f284466779a628f0201c2 (patch) | |
tree | 83ca835bf36a9cade34ec464982b44df309bc7b8 /src/structs.rs | |
parent | a8e1517fd1ad2fa30b9fc68d3e7b58cf9b680e1f (diff) | |
parent | db532edb6b63912f6cce0c5b6445b37686473069 (diff) |
Merge branch 'master' of kobert:/var/repos/babel
Diffstat (limited to 'src/structs.rs')
-rw-r--r-- | src/structs.rs | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/structs.rs b/src/structs.rs new file mode 100644 index 0000000..fdc20f4 --- /dev/null +++ b/src/structs.rs @@ -0,0 +1,132 @@ +pub struct StoneWall { + rows: Vec<Vec<u32>>, +} + +impl StoneWall { + 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); + rows.get_mut(1).map(|r| r[1] = 2); + Self { + rows, + } + } + + 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) + } + + pub fn output(&self) { + let colors = [ + [31, 32], + [33, 35], + ]; + 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<u32>, +} + +impl GapHeights { + pub fn from_heights(heights: Vec<u32>) -> 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 } + } + + pub fn add_gap(&mut self, height: u32) { + self.add_gap(height) + } + + 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"); + } + } + + pub fn iter<'a>(&'a self) -> GapIter<'a> { + GapIter { + gap_heights: self, + i: 0, + } + } + + 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<Self::Item> { + let i = self.i; + self.i += 1; + self.gap_heights.heights.get(i).map(|&x| x) + } +} |