From ff241d76cb1c683665cb3701977d05ad702797ad Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Mon, 16 Dec 2024 20:27:25 +0100 Subject: [PATCH] pre y2024d16p2 --- y2024/src/days/d16.rs | 103 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/y2024/src/days/d16.rs b/y2024/src/days/d16.rs index 67671ad..14c8bda 100644 --- a/y2024/src/days/d16.rs +++ b/y2024/src/days/d16.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, error::Error}; +use std::{ + collections::{HashMap, HashSet}, + error::Error, +}; use itertools::Itertools; @@ -61,7 +64,75 @@ pub fn process_part1(input: &str) -> usize { } pub fn process_part2(input: &str) -> usize { - 0 + let mut start = (0, 0); + let mut end = (0, 0); + let grid = input + .lines() + .enumerate() + .map(|(yidx, row)| { + row.chars() + .enumerate() + .map(|(xidx, chara)| { + let tile = GridTile::try_from(chara).unwrap(); + match tile { + GridTile::Wall | GridTile::Path => tile, + GridTile::Start => { + start = (xidx, yidx); + tile + } + GridTile::End => { + end = (xidx, yidx); + tile + } + } + }) + .collect_vec() + }) + .collect_vec(); + let mut visited = HashSet::new(); + visited.insert(start); + let mut next_paths = vec![Reindeer { + coords: start, + visited, + ..Default::default() + }]; + let mut arrived: Vec = Vec::new(); + let mut visited = HashMap::new(); + while !next_paths.is_empty() { + next_paths = next_paths + .iter() + .map(|reindeer| reindeer.get_all_next_paths(&grid)) + .collect_vec() + .concat(); + for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() { + if let Some(_score) = visited.get_mut(&reindeer.coords) { + //if *score < reindeer.score { + // next_paths.remove(idx); + // continue; + //} else { + // *score = reindeer.score; + //} + } else { + visited.insert(reindeer.coords, reindeer.score); + } + if reindeer.state == ReindeerState::Arrived { + let arrived_reindeer = next_paths.remove(idx); + arrived.push(arrived_reindeer); + } + } + } + let min_score = arrived.iter().map(|reindeer| reindeer.score).min().unwrap(); + let visited = arrived + .into_iter() + .filter(|reindeer| reindeer.score == min_score) + .collect_vec(); + println!("{visited:?}"); + let visited = visited + .into_iter() + .map(|reindeer| reindeer.visited.into_iter().collect_vec()) + .collect_vec() + .concat(); + visited.iter().unique().count() } #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] @@ -101,11 +172,12 @@ enum ReindeerState { Stuck, } -#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] struct Reindeer { orientation: Orientation, coords: (usize, usize), score: usize, + visited: HashSet<(usize, usize)>, state: ReindeerState, } @@ -123,9 +195,12 @@ impl Reindeer { Orientation::South => (self.coords.0, self.coords.1 + 1), Orientation::North => (self.coords.0, self.coords.1 - 1), }; + let mut visited = self.visited.clone(); + visited.insert(coords); if tile == GridTile::Wall { Reindeer { state: ReindeerState::Stuck, + visited, ..*self } } else if tile == GridTile::End { @@ -133,12 +208,14 @@ impl Reindeer { score: self.score + 1, state: ReindeerState::Arrived, coords, + visited, ..*self } } else { Reindeer { score: self.score + 1, coords, + visited, ..*self } } @@ -157,9 +234,12 @@ impl Reindeer { Orientation::South => (self.coords.0 - 1, self.coords.1), Orientation::North => (self.coords.0 + 1, self.coords.1), }; + let mut visited = self.visited.clone(); + visited.insert(coords); if tile == GridTile::Wall { Reindeer { state: ReindeerState::Stuck, + visited, ..*self } } else if tile == GridTile::End { @@ -168,12 +248,14 @@ impl Reindeer { state: ReindeerState::Arrived, coords, orientation: self.orientation.turn_clockwise(), + visited, } } else { Reindeer { score: self.score + 1001, orientation: self.orientation.turn_clockwise(), coords, + visited, ..*self } } @@ -192,9 +274,12 @@ impl Reindeer { Orientation::South => (self.coords.0 + 1, self.coords.1), Orientation::North => (self.coords.0 - 1, self.coords.1), }; + let mut visited = self.visited.clone(); + visited.insert(coords); if tile == GridTile::Wall { Reindeer { state: ReindeerState::Stuck, + visited, ..*self } } else if tile == GridTile::End { @@ -203,12 +288,14 @@ impl Reindeer { state: ReindeerState::Arrived, coords, orientation: self.orientation.turn_counterclockwise(), + visited, } } else { Reindeer { score: self.score + 1001, orientation: self.orientation.turn_counterclockwise(), coords, + visited, ..*self } } @@ -306,8 +393,14 @@ mod tests { } #[test] - fn part2() { + fn part2_1() { let result = process_part2(INPUT_1); - assert_eq!(result, 0); + assert_eq!(result, 45); + } + + #[test] + fn part2_2() { + let result = process_part2(INPUT_2); + assert_eq!(result, 64); } }