summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2023-12-14 14:13:50 +0100
committerReiner Herrmann <reiner@reiner-h.de>2023-12-14 14:13:50 +0100
commit1ca89e06a2949ca91e169ce1c80821128fc19614 (patch)
treedd203c10ad204aa27f6302be38a9f1bf35b6fafc
parent22b8be0ca3ec4af1d879b15190ef1ff574ac5475 (diff)
day14 solution 1
-rw-r--r--src/bin/day14.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/bin/day14.rs b/src/bin/day14.rs
new file mode 100644
index 0000000..6c3f0df
--- /dev/null
+++ b/src/bin/day14.rs
@@ -0,0 +1,100 @@
+use std::collections::HashSet;
+
+static DAY: u8 = 14;
+
+fn main() {
+ let input = advent::read_lines(DAY);
+ println!("{DAY}a: {}", total_load(&input));
+ println!("{DAY}b: {}", 0);
+}
+
+#[derive(PartialEq, Eq, Hash, Clone, Copy)]
+struct Position {
+ x: isize,
+ y: isize,
+}
+
+struct Map {
+ round_rocks: HashSet<Position>,
+ cube_rocks: HashSet<Position>,
+ _width: isize,
+ height: isize,
+}
+
+impl Map {
+ fn new(input: &[String]) -> Map {
+ let mut round_rocks = HashSet::new();
+ let mut cube_rocks = HashSet::new();
+
+ for (y, line) in input.iter().enumerate() {
+ for (x, rock) in line.chars().enumerate() {
+ let pos = Position { x: x as isize, y: y as isize };
+ match rock {
+ '#' => { cube_rocks.insert(pos); }
+ 'O' => { round_rocks.insert(pos); }
+ _ => {},
+ }
+ }
+ }
+
+ Map { round_rocks, cube_rocks, _width: input[0].len() as isize, height: input.len() as isize }
+ }
+
+ fn tilt(&mut self) {
+ loop {
+ let mut round_rocks = self.round_rocks.clone();
+
+ for rock in &self.round_rocks {
+ round_rocks.remove(rock);
+ let mut new_pos = *rock;
+ for y in (0 .. rock.y).rev() {
+ let pos = Position { x: rock.x, y };
+ if self.cube_rocks.contains(&pos) || round_rocks.contains(&pos) {
+ break;
+ }
+ new_pos = pos;
+ }
+ round_rocks.insert(new_pos);
+ }
+
+ if self.round_rocks == round_rocks {
+ break;
+ }
+ self.round_rocks = round_rocks;
+ }
+ }
+
+ fn load(&self) -> isize {
+ self.round_rocks.iter()
+ .map(|rock| self.height - rock.y)
+ .sum()
+ }
+}
+
+fn total_load(input: &[String]) -> isize {
+ let mut map = Map::new(input);
+ map.tilt();
+ map.load()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ let input = [
+ "O....#....",
+ "O.OO#....#",
+ ".....##...",
+ "OO.#O....O",
+ ".O.....O#.",
+ "O.#..O.#.#",
+ "..O..#O..O",
+ ".......O..",
+ "#....###..",
+ "#OO..#....",
+ ].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
+ assert_eq!(total_load(&input), 136);
+ }
+}