From: Jack Kinsey Date: Fri, 20 Dec 2024 03:27:44 +0000 (-0500) Subject: Make partial progress on 15.2 X-Git-Url: http://git.jkinsey.net/?a=commitdiff_plain;h=71389bd09c8448e816a6d92f431ae35d5f913e50;p=adventofcode2024.git Make partial progress on 15.2 --- diff --git a/src/day15.rs b/src/day15.rs index 8308212..809f4b9 100644 --- a/src/day15.rs +++ b/src/day15.rs @@ -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, Vec) { struct RobotPrediction { map: Map, robot: Point, + wide: bool, } impl RobotPrediction { fn new(map: Map) -> Self { let robot = map.find(Tile::Robot).next().unwrap(); - RobotPrediction { map, robot } + RobotPrediction { + map, + robot, + wide: false, + } + } + + fn new_wide(map: Map) -> 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] ]), ) }