diff options
author | kdx <kikoodx@paranoici.org> | 2023-12-10 23:56:08 +0100 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-12-10 23:56:08 +0100 |
commit | 49d83183fa41c7b8e6f126d8df0591d6698cd9e2 (patch) | |
tree | 84e62a5274312fff91ad7d8453b7a31060f114cf | |
parent | e68b2c1e20187dc81d46478a284297f3d0651358 (diff) | |
download | aoc23-49d83183fa41c7b8e6f126d8df0591d6698cd9e2.tar.gz |
10 rust
-rw-r--r-- | 10/rust/src/main.rs | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/10/rust/src/main.rs b/10/rust/src/main.rs index 7c0c3fe..7afe2e4 100644 --- a/10/rust/src/main.rs +++ b/10/rust/src/main.rs @@ -1,69 +1,98 @@ use std::io::BufRead; +#[derive(Debug)] struct Grid(Vec<String>); impl Grid { fn at(&self, x: isize, y: isize) -> char { - return self.0[y as usize].chars().nth(x as usize).unwrap(); + if x < 0 || y < 0 { + return '\0'; + } + let y = y as usize; + let x = x as usize; + if y >= self.0.len() || x >= self.0[y].len() { + return '\0'; + } + return self.0[y].chars().nth(x).unwrap(); + } + + fn set(&mut self, x: isize, y: isize, c: char) { + let y = y as usize; + let x = x as usize; + self.0[y].replace_range(x..x + 1, &c.to_string()); + } + + fn flood(&mut self, x: isize, y: isize) -> usize { + let v = match self.at(x, y) { + ' ' => 0, + '.' => 1, + _ => return 0 + }; + self.set(x, y, '#'); + return v + self.flood(x + 1, y) + + self.flood(x - 1, y) + + self.flood(x, y + 1) + + self.flood(x, y - 1); + } + + fn traverse(&self, expanded: &mut Grid, start_x: isize, start_y: isize) { + let mut x = start_x; + let mut y = start_y; + let mut dir_x = 0isize; + let mut dir_y = 0isize; + + if "-LF".contains(self.at(x - 1, y)) { + dir_x = -1; + } else if "-J7".contains(self.at(x + 1, y)) { + dir_x = 1; + } else if "|7F".contains(self.at(x, y - 1)) { + dir_y = -1; + } else if "|JL".contains(self.at(x, y + 1)) { + dir_y = 1; + } else { + panic!("no valid adjacent pipe found"); + } + + loop { + expanded.set(x * 2, y * 2, '#'); + expanded.set(x * 2 + dir_x, y * 2 + dir_y, '#'); + x += dir_x; + y += dir_y; + match self.at(x, y) { + '-' | '|' => (), + '7' | 'L' => (dir_x, dir_y) = (dir_y, dir_x), + 'F' | 'J' => (dir_x, dir_y) = (-dir_y, -dir_x), + 'S' => break, + _ => unreachable!(), + } + } } } fn main() { - let mut grid: Grid = Grid(vec![]); + let mut grid = Grid(vec![]); for line in std::io::stdin().lock().lines() { grid.0.push(line.unwrap()); } + let mut expanded = Grid(vec![]); let mut start_x = 0; let mut start_y = 0; - 'outer: for (y, line) in grid.0.iter().enumerate() { + for (y, line) in grid.0.iter().enumerate() { for (x, c) in line.chars().enumerate() { if c == 'S' { start_x = x; start_y = y; - break 'outer; } } + expanded.0.push(". ".repeat(line.len())); + expanded.0.push(" ".repeat(line.len())); } assert!(start_x != 0); assert!(start_y != 0); - println!( - "{}", - traverse(&grid, start_x as isize, start_y as isize) / 2 - ); -} - -fn traverse(grid: &Grid, start_x: isize, start_y: isize) -> usize { - let mut x = start_x; - let mut y = start_y; - let mut dir_x = 0isize; - let mut dir_y = 0isize; - let mut steps = 1; + grid.traverse(&mut expanded, start_x as isize, start_y as isize); - if "-LF".contains(grid.at(x - 1, y)) { - dir_x = -1; - } else if "-J7".contains(grid.at(x + 1, y)) { - dir_x = 1; - } else if "|7F".contains(grid.at(x, y - 1)) { - dir_y = -1; - } else if "|JL".contains(grid.at(x, y + 1)) { - dir_y = 1; - } else { - panic!("no valid adjacent pipe found"); - } - - loop { - steps += 1; - x += dir_x; - y += dir_y; - match grid.at(x, y) { - '-' | '|' => (), - '7' | 'L' => (dir_x, dir_y) = (dir_y, dir_x), - 'F' | 'J' => (dir_x, dir_y) = (-dir_y, -dir_x), - 'S' => return steps, - _ => unreachable!(), - } - } + println!("{}", expanded.flood(grid.0[0].len() as isize, grid.0.len() as isize)); } |