diff --git a/day22/src/main.rs b/day22/src/main.rs index 5bdc6b4..de64d91 100644 --- a/day22/src/main.rs +++ b/day22/src/main.rs @@ -15,13 +15,15 @@ enum SolvePuzzle { } fn solve_first_puzzle(reader: R) -> usize { - let map = Map::parse(reader); + let map = Map::::parse(reader); map.display(); map.crack_password() } -fn solve_second_puzzle(reader: R) -> usize { - todo!() +fn solve_second_puzzle(reader: R) -> usize { + let map = Map::::parse(reader); + map.display(); + map.crack_password() } fn main() { @@ -38,7 +40,7 @@ fn main() { let file = BufReader::new(File::open(file).expect("Opening file")); match solve { SolvePuzzle::First => println!("{}", solve_first_puzzle(file)), - SolvePuzzle::Second => println!("{}", solve_second_puzzle(file)), + SolvePuzzle::Second => println!("{}", solve_second_puzzle::<50, _>(file)), }; } @@ -51,12 +53,12 @@ mod tests { #[test] fn example_on_first() { let reader = Cursor::new(include_str!("../input.test")); - assert_eq!(solve_first_puzzle(reader), 152); + assert_eq!(solve_first_puzzle(reader), 6032); } #[test] fn example_on_second() { let reader = Cursor::new(include_str!("../input.test")); - assert_eq!(solve_second_puzzle(reader), 301); + assert_eq!(solve_second_puzzle::<4, _>(reader), 5031); } } diff --git a/day22/src/map.rs b/day22/src/map.rs index a87f69e..95443de 100644 --- a/day22/src/map.rs +++ b/day22/src/map.rs @@ -7,6 +7,7 @@ pub enum Facing { South, West, } + impl Facing { fn turn_left(&mut self) { *self = match self { @@ -26,15 +27,6 @@ impl Facing { } } - fn opposite(&self) -> Self { - match self { - Facing::North => Facing::South, - Facing::East => Facing::West, - Facing::South => Facing::North, - Facing::West => Facing::East, - } - } - fn to_number(&self) -> usize { match self { Facing::North => 3, @@ -99,13 +91,13 @@ impl Action { } #[derive(Debug)] -pub struct Map { +pub struct Map { tiles: Vec, width: usize, actions: Vec, } -impl Map { +impl Map { pub fn parse(reader: R) -> Self { let mut lines: Vec = reader.lines().map(Result::unwrap).collect(); let instructions = lines.pop().expect("Instructions on the last line"); @@ -153,28 +145,37 @@ impl Map { pub fn crack_password(&self) -> usize { let (mut x, mut y) = self.first_position(); + println!("-- ({:>2}, {:>2})", x + 1, y + 1); let mut facing = Facing::East; - 'label: for action in &self.actions { + let width = self.width; + let height = self.tiles.len() / self.width; + for action in &self.actions { + println!("DIR : {facing:?}"); + println!("ACTION: {action:?}"); match action { Action::Move(amount) => { for _step in 0..*amount { let raw_potential_new_position = match facing { - Facing::North => (x, y - 1), + Facing::North => (x, if y == 0 { height - 1 } else { y - 1 }), Facing::East => (x + 1, y), Facing::South => (x, y + 1), - Facing::West => (x - 1, y), + Facing::West => (if x == 0 { width - 1 } else { x - 1 }, y), }; let potential_new_position = self.wrap_position(raw_potential_new_position, facing); if self[potential_new_position] == Tile::Solid { - break 'label; + break; } + x = potential_new_position.0; + y = potential_new_position.1; + println!("-> ({:>2}, {:>2})", x + 1, y + 1); } } Action::Left => facing.turn_left(), Action::Right => facing.turn_right(), } } + println!("> {} {} {}", x + 1, y + 1, facing.to_number()); 1000 * (y + 1) + 4 * (x + 1) + facing.to_number() } @@ -192,12 +193,22 @@ impl Map { let wrap_array = |x: usize, y: usize| (x % self.width, y % height); let (x, y) = wrap_array(x, y); if self[(x, y)] == Tile::Void { + let mut next = (x, y); loop { - let next = match facing { - Facing::North => wrap_array(x, if y == 0 { height - 1 } else { y - 1 }), - Facing::East => wrap_array(x + 1, y), - Facing::South => wrap_array(x, y + 1), - Facing::West => wrap_array(if x == 0 { self.width - 1 } else { x - 1 }, y), + next = match facing { + Facing::North => { + wrap_array(next.0, if next.1 == 0 { height - 1 } else { next.1 - 1 }) + } + Facing::East => wrap_array(next.0 + 1, next.1), + Facing::South => wrap_array(next.0, next.1 + 1), + Facing::West => wrap_array( + if next.0 == 0 { + self.width - 1 + } else { + next.0 - 1 + }, + next.1, + ), }; if self[next] != Tile::Void { break next; @@ -209,7 +220,9 @@ impl Map { } } -impl Index<(usize, usize)> for Map { +impl Index<(usize, usize)> + for Map +{ type Output = Tile; fn index(&self, (x, y): (usize, usize)) -> &Self::Output {