]> localhost Git - adventofcode2024.git/commitdiff
Make partial progress on 15.2
authorJack Kinsey <j.jameskinsey@gmail.com>
Fri, 20 Dec 2024 03:27:44 +0000 (22:27 -0500)
committerJack Kinsey <j.jameskinsey@gmail.com>
Fri, 20 Dec 2024 03:27:44 +0000 (22:27 -0500)
src/day15.rs

index 8308212118f24e18a1e1e5d734a5f00d0dc41cc6..809f4b9f57842dca29d409a5b4a7f9ebe6e77a46 100644 (file)
@@ -4,11 +4,6 @@ use std::ops::{Add, Index, IndexMut, Sub};
 struct Point(i32, i32);
 
 impl Point {
-    fn in_bounds(&self, bound: usize) -> bool {
-        let bound: i32 = bound.try_into().unwrap();
-        self.0 >= 0 && self.1 >= 0 && self.0 < bound && self.1 < bound
-    }
-
     fn move_in(&self, dir: Dir) -> Point {
         match dir {
             Dir::N => *self + Point(-1, 0),
@@ -18,6 +13,15 @@ impl Point {
         }
     }
 
+    fn moved_from(&self, dir: Dir) -> Point {
+        self.move_in(match dir {
+            Dir::N => Dir::S,
+            Dir::E => Dir::W,
+            Dir::S => Dir::N,
+            Dir::W => Dir::E,
+        })
+    }
+
     fn gps(&self) -> u64 {
         (100 * self.0 + self.1).try_into().unwrap()
     }
@@ -149,12 +153,80 @@ fn parse(input: &str) -> (Map<Tile>, Vec<Dir>) {
 struct RobotPrediction {
     map: Map<Tile>,
     robot: Point,
+    wide: bool,
 }
 
 impl RobotPrediction {
     fn new(map: Map<Tile>) -> Self {
         let robot = map.find(Tile::Robot).next().unwrap();
-        RobotPrediction { map, robot }
+        RobotPrediction {
+            map,
+            robot,
+            wide: false,
+        }
+    }
+
+    fn new_wide(map: Map<Tile>) -> Self {
+        let robot = map.find(Tile::Robot).next().unwrap();
+        RobotPrediction {
+            map,
+            robot,
+            wide: true,
+        }
+    }
+
+    fn one_box(&mut self, inst: Dir, np: Point) {
+        let mut mp = np.move_in(inst);
+        loop {
+            mp = match self.map[mp] {
+                Tile::Space => {
+                    self.map[self.robot] = Tile::Space;
+                    self.map[np] = Tile::Robot;
+                    self.map[mp] = Tile::Box;
+                    self.robot = np;
+                    break;
+                }
+                Tile::Wall => break,
+                Tile::Box => mp.move_in(inst),
+                Tile::BoxL => unreachable!(),
+                Tile::BoxR => unreachable!(),
+                Tile::Robot => unreachable!(),
+            }
+        }
+    }
+
+    fn two_box(&mut self, inst: Dir, mover: Tile, np: Point, lp: Point, rp: Point) {
+        match (self.map[lp], self.map[rp]) {
+            (Tile::Space, Tile::Space) => {
+                self.map[np] = mover;
+                self.map[lp] = Tile::BoxL;
+                self.map[rp] = Tile::BoxR;
+                if mover == Tile::Robot {
+                    self.map[self.robot] = Tile::Space;
+                    self.robot = np;
+                }
+                todo!()
+            }
+            (Tile::Wall, _) | (_, Tile::Wall) => (),
+            (Tile::BoxL, Tile::BoxR) => {
+                self.two_box(inst, (), np, lp.move_in(inst), rp.move_in(inst));
+                todo!()
+            }
+            (Tile::BoxR, Tile::BoxL) => todo!(),
+            (Tile::BoxL, Tile::Space) | (Tile::Space, Tile::BoxL) => {
+                let lp = np.move_in(inst);
+                let rp = lp + Point(0, 1);
+                self.two_box(inst, (), np, lp, rp);
+                todo!()
+            }
+            (Tile::BoxR, Tile::Space) | (Tile::Space, Tile::BoxR) => {
+                let rp = np.move_in(inst);
+                let lp = rp - Point(0, 1);
+                self.two_box(inst, (), np, lp, rp);
+                todo!()
+            }
+            _ => unreachable!(),
+        }
     }
 
     fn apply(&mut self, inst: Dir) {
@@ -166,28 +238,18 @@ impl RobotPrediction {
                 self.robot = np;
             }
             Tile::Wall => (),
-            Tile::Box => {
-                let mut mp = np.move_in(inst);
-                loop {
-                    mp = match self.map[mp] {
-                        Tile::Space => {
-                            self.map[self.robot] = Tile::Space;
-                            self.map[np] = Tile::Robot;
-                            self.map[mp] = Tile::Box;
-                            self.robot = np;
-                            break;
-                        }
-                        Tile::Wall => break,
-                        Tile::Box => mp.move_in(inst),
-                        Tile::Robot => unreachable!(),
-                        Tile::BoxL => todo!(),
-                        Tile::BoxR => todo!(),
-                    }
-                }
+            Tile::Box => self.one_box(inst, np),
+            Tile::BoxL => {
+                let lp = np.move_in(inst);
+                let rp = lp + Point(0, 1);
+                self.two_box(inst, Tile::Robot, np, lp, rp);
+            }
+            Tile::BoxR => {
+                let rp = np.move_in(inst);
+                let lp = rp - Point(0, 1);
+                self.two_box(inst, Tile::Robot, np, lp, rp);
             }
             Tile::Robot => unreachable!(),
-            Tile::BoxL => todo!(),
-            Tile::BoxR => todo!(),
         }
     }
     // println!("{:?} -> {:?}\n{:#?}", self.robot, np, self.map);
@@ -210,7 +272,10 @@ pub fn part1(input: &str) -> u64 {
 }
 
 pub fn part2(input: &str) -> u64 {
-    0
+    let (map, inst) = parse(input);
+    let mut pred = RobotPrediction::new_wide(map.biggerify());
+    pred.simulate(&inst);
+    pred.map.find(Tile::BoxL).map(|p| p.gps()).sum()
 }
 
 #[cfg(test)]
@@ -318,7 +383,8 @@ mod test {
 
     #[test]
     fn test_gps_sum() {
-        assert_eq!(part1(INPUT_STR), 10092)
+        assert_eq!(part1(INPUT_STR), 10092);
+        assert_eq!(part2(INPUT_STR), 9021);
     }
 
     #[rustfmt::skip]
@@ -329,46 +395,26 @@ mod test {
         assert_eq!(
             map.biggerify(),
             Map(vec![
-                vec![
-                    Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall,
-                    Wall, Wall, Wall, Wall, Wall, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, Space, Space, BoxL, BoxR, Space, Space, Space, Space,
-                    BoxL, BoxR, Space, Space, BoxL, BoxR, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, Space, Space, Space, Space, Space, Space, Space,
-                    Space, Space, Space, BoxL, BoxR, Space, Space, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, BoxL, BoxR, BoxL, BoxR, Space, Space, Space, Space,
-                    BoxL, BoxR, Space, Space, BoxL, BoxR, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, Space, Space, BoxL, BoxR, Robot, Space, Space, Space,
-                    Space, Space, BoxL, BoxR, Space, Space, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, BoxL, BoxR, Wall, Wall, Space, Space, Space, Space, BoxL, BoxR,
-                    Space, Space, Space, Space, Space, Space, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, BoxL, BoxR, Space, Space, Space, Space, BoxL, BoxR, Space, Space,
-                    Space, Space, BoxL, BoxR, Space, Space, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, BoxL, BoxR, BoxL, BoxR, Space, Space, BoxL, BoxR,
-                    Space, Space, BoxL, BoxR, BoxL, BoxR, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Space, Space, Space, Space, Space, Space, Space, Space, BoxL, BoxR,
-                    Space, Space, Space, Space, Space, Space, Wall, Wall
-                ],
-                vec![
-                    Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall,
-                    Wall, Wall, Wall, Wall, Wall, Wall, Wall
-                ]
+                vec![Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall,
+                     Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall],
+                vec![Wall, Wall, Space, Space, Space, Space, BoxL, BoxR, Space, Space,
+                     Space, Space, BoxL, BoxR, Space, Space, BoxL, BoxR, Wall, Wall],
+                vec![Wall, Wall, Space, Space, Space, Space, Space, Space, Space, Space,
+                     Space, Space, Space, Space, BoxL, BoxR, Space, Space, Wall, Wall],
+                vec![Wall, Wall, Space, Space, BoxL, BoxR, BoxL, BoxR, Space, Space,
+                     Space, Space, BoxL, BoxR, Space, Space, BoxL, BoxR, Wall, Wall],
+                vec![Wall, Wall, Space, Space, Space, Space, BoxL, BoxR, Robot, Space,
+                     Space, Space, Space, Space, BoxL, BoxR, Space, Space, Wall, Wall],
+                vec![Wall, Wall, BoxL, BoxR, Wall, Wall, Space, Space, Space, Space,
+                     BoxL, BoxR, Space, Space, Space, Space, Space, Space, Wall, Wall],
+                vec![Wall, Wall, BoxL, BoxR, Space, Space, Space, Space, BoxL, BoxR,
+                     Space, Space, Space, Space, BoxL, BoxR, Space, Space, Wall, Wall],
+                vec![Wall, Wall, Space, Space, BoxL, BoxR, BoxL, BoxR, Space, Space,
+                     BoxL, BoxR, Space, Space, BoxL, BoxR, BoxL, BoxR, Wall, Wall],
+                vec![Wall, Wall, Space, Space, Space, Space, Space, Space, Space, Space,
+                     BoxL, BoxR, Space, Space, Space, Space, Space, Space, Wall, Wall],
+                vec![Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall,
+                     Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall]
             ]),
         )
     }