pre y2024d16p2
This commit is contained in:
		| @@ -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<Reindeer> = 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); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user