summary refs log tree commit diff
path: root/25/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '25/src/main.rs')
-rw-r--r--25/src/main.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/25/src/main.rs b/25/src/main.rs
new file mode 100644
index 0000000..2e137c7
--- /dev/null
+++ b/25/src/main.rs
@@ -0,0 +1,118 @@
+use advent_lib::prelude::*;
+
+#[derive(Debug,Clone,Eq,PartialEq)]
+enum Cell {
+  Empty,
+  East,
+  South,
+}
+
+
+fn main() -> Result<()> {
+  let mut args = std::env::args();
+  if args.len() != 2 {
+    eprintln!("Usage: advent input");
+  }
+  let _ = args.next();
+  let filename = args.next().unwrap();
+
+  let input = advent_lib::read_lines_file(&filename)?;
+
+  let mut initial_grid = Vec::new();
+  for line in &input {
+    let mut row = Vec::new();
+    for c in line.chars() {
+      row.push(match c {
+        '.' => Cell::Empty,
+        '>' => Cell::East,
+        'v' => Cell::South,
+        _ => panic!("Unrecognized character."),
+      });
+    }
+    initial_grid.push(row);
+  }
+
+  let mut i = 0;
+  let mut grid = initial_grid.clone();
+  loop {
+    i += 1;
+    let (anything_moved, new_grid) = iterate(&grid);
+    grid = new_grid;
+
+    println!("iteration {}", i);
+    debug_grid(&grid);
+
+    if !anything_moved {
+      break;
+    }
+  }
+  println!("{}", i);
+
+  Ok(())
+}
+
+
+fn iterate(grid: &Vec<Vec<Cell>>) -> (bool, Vec<Vec<Cell>>) {
+  let mut anything_moved = false;
+
+  let height = grid.len();
+  let width = grid[0].len();
+
+  let mut new_grid = Vec::new();
+  for _ in 0 .. height {
+    let mut row = Vec::new();
+    for _ in 0 .. width {
+      row.push(Cell::Empty);
+    }
+    new_grid.push(row);
+  }
+
+  for y in 0 .. height {
+    for x in 0 .. width {
+      if grid[y][x] == Cell::East {
+        let new_x = (x + 1) % width;
+        if grid[y][new_x] == Cell::Empty {
+          new_grid[y][new_x] = Cell::East;
+          anything_moved = true;
+        } else {
+          new_grid[y][x] = Cell::East;
+        }
+      }
+    }
+  }
+
+  for y in 0 .. height {
+    for x in 0 .. width {
+      if grid[y][x] == Cell::South {
+        let new_y = (y + 1) % height;
+        if new_grid[new_y][x] == Cell::Empty
+          && grid[new_y][x] != Cell::South
+        {
+          new_grid[new_y][x] = Cell::South;
+          anything_moved = true;
+        } else {
+          new_grid[y][x] = Cell::South;
+        }
+      }
+    }
+  }
+
+  (anything_moved, new_grid)
+}
+
+
+#[allow(dead_code)]
+fn debug_grid(grid: &Vec<Vec<Cell>>) {
+  for row in grid {
+    for cell in row {
+      match cell {
+        Cell::Empty => print!("."),
+        Cell::East => print!(">"),
+        Cell::South => print!("v"),
+      }
+    }
+    println!("");
+  }
+  println!("");
+}
+