summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-12-10 23:56:08 +0100
committerkdx <kikoodx@paranoici.org>2023-12-10 23:56:08 +0100
commit49d83183fa41c7b8e6f126d8df0591d6698cd9e2 (patch)
tree84e62a5274312fff91ad7d8453b7a31060f114cf
parente68b2c1e20187dc81d46478a284297f3d0651358 (diff)
downloadaoc23-49d83183fa41c7b8e6f126d8df0591d6698cd9e2.tar.gz
10 rust
-rw-r--r--10/rust/src/main.rs109
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));
}