diff --git a/2023/day5/src/main.rs b/2023/day5/src/main.rs index 9971a8e..09f409e 100644 --- a/2023/day5/src/main.rs +++ b/2023/day5/src/main.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, VecDeque}; use std::ops::Range; use DataType::*; -const FILE_STR: &'static str = include_str!("input.txt"); +const FILE_STR: &str = include_str!("input.txt"); #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] enum DataType { @@ -109,7 +109,7 @@ impl Almanac { let maps = data_chunks .into_iter() .map(|chunk| { - let mut lines: VecDeque<_> = chunk.split("\n").collect(); + let mut lines: VecDeque<_> = chunk.split('\n').collect(); let type_line_parts: Vec<_> = lines.pop_front().unwrap().split_whitespace().collect(); let types: Vec<_> = type_line_parts[0] @@ -119,11 +119,11 @@ impl Almanac { let (from, to) = (types[0], types[1]); let mappings: Vec = lines .into_iter() - .filter(|l| l.len() > 0) + .filter(|l| !l.is_empty()) .map(|line| { line.split_whitespace() .map(|s| s.trim()) - .filter(|s| s.len() > 0) + .filter(|s| !s.is_empty()) .map(|s| s.parse::().unwrap()) .collect::>() }) @@ -144,11 +144,10 @@ impl Almanac { fn x_from_y(&self, x: DataType, y: DataType, search: u64) -> u64 { self.maps .get(&(y, x)) - .expect(&format!("Missing mapping from {:?} to {:?}", x, y)) - .into_iter() - .filter(|dm| dm.to_range.contains(&search)) + .unwrap_or_else(|| panic!("Missing mapping from {:?} to {:?}", x, y)) + .iter() .find_map(|dm| dm.get_dest_idx(search)) - .unwrap_or_else(|| search) + .unwrap_or(search) } fn location_from_seed(&self, seed: u64) -> u64 { @@ -162,31 +161,36 @@ impl Almanac { self.x_from_y(Location, Humidity, humid) } - fn locations_from_seeds(&self) -> HashMap { + fn locations_from_seeds(&self) -> Vec { self.seeds .iter() - .map(|s| (*s, self.location_from_seed(*s))) + .map(|s| self.x_from_y(Soil, Seed, *s)) + .map(|s| self.x_from_y(Fertilizer, Soil, s)) + .map(|f| self.x_from_y(Water, Fertilizer, f)) + .map(|w| self.x_from_y(Light, Water, w)) + .map(|l| self.x_from_y(Temperature, Light, l)) + .map(|t| self.x_from_y(Humidity, Temperature, t)) + .map(|h| self.x_from_y(Location, Humidity, h)) .collect() } fn lowest_seed_location(&self) -> u64 { - self.locations_from_seeds() - .iter() - .map(|(_, l)| *l) - .min() - .unwrap() + self.locations_from_seeds().iter().copied().min().unwrap() } fn lowest_seed_range_location(&self) -> u64 { + let range_flattener = |r: Range| r.clone().collect::>(); self.seed_ranges - .iter() - .map(|r| { - r.clone() - .into_iter() - .map(|s| self.location_from_seed(s)) - .min() - .unwrap() - }) + .clone() + .into_iter() + .flat_map(range_flattener) + .map(|s| self.x_from_y(Soil, Seed, s)) + .map(|s| self.x_from_y(Fertilizer, Soil, s)) + .map(|f| self.x_from_y(Water, Fertilizer, f)) + .map(|w| self.x_from_y(Light, Water, w)) + .map(|l| self.x_from_y(Temperature, Light, l)) + .map(|t| self.x_from_y(Humidity, Temperature, t)) + .map(|h| self.x_from_y(Location, Humidity, h)) .min() .unwrap() } @@ -229,7 +233,7 @@ mod tests { #[test] fn test_locations_from_seeds() { let almanac = Almanac::parse(EXAMPLE_FILE_STR); - let expected = HashMap::from([(79, 82), (14, 43), (55, 86), (13, 35)]); + let expected = Vec::from([82, 43, 86, 35]); assert_eq!(expected, almanac.locations_from_seeds()); }