From 875af88c7494b39183777d06f616988dadd19a94 Mon Sep 17 00:00:00 2001 From: Jack Kinsey Date: Wed, 11 Dec 2024 00:46:56 -0500 Subject: [PATCH] Tidy up day 10 --- src/day10.rs | 130 ++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/src/day10.rs b/src/day10.rs index 7848b25..d61cf65 100644 --- a/src/day10.rs +++ b/src/day10.rs @@ -1,4 +1,4 @@ -use std::collections::{HashSet, VecDeque}; +use std::collections::HashSet; use std::ops::{Add, Index, Sub}; fn input() -> &'static str { @@ -58,64 +58,68 @@ impl Index for Map { } } -fn parse(input: &str) -> Map { - Map(input - .lines() - .map(|l| l.chars().map(|c| c.to_string().parse().unwrap()).collect()) - .collect()) -} - -fn find_height(map: &Map, height: u8) -> impl Iterator + use<'_> { - map.0.iter().zip(0..).flat_map(move |(v, i)| { - v.iter() - .zip(0..) - .filter(move |(&c, _)| c == height) - .map(move |(_, j)| Point(i, j)) - }) -} +impl Map { + fn find_height(&self, height: u8) -> impl Iterator + use<'_> { + self.0.iter().zip(0..).flat_map(move |(v, i)| { + v.iter() + .zip(0..) + .filter(move |(&c, _)| c == height) + .map(move |(_, j)| Point(i, j)) + }) + } -fn walk_paths(map: &Map, root: &Point) -> Vec { - let bound = map.0.len(); - let mut adjits = VecDeque::from([root.adjacent(bound)]); - let mut adjs: Vec = vec![]; - for n in 1..=9 { - while let Some(adj) = adjits.pop_front() { - adjs.extend(adj); - } - if n < 9 { - while let Some(p) = adjs.pop() { - if map[p] == n { - adjits.push_back(p.adjacent(bound)) + fn walk_paths(&self, root: &Point) -> Vec { + let bound = self.0.len(); + let mut iterators = vec![]; + let mut points = vec![*root]; + for n in 0..9 { + iterators.extend(points.drain(..).filter_map(|p| { + if self[p] == n { + Some(p.adjacent(bound)) + } else { + None } - } + })); + points.extend(iterators.drain(..).flatten()); } + points.into_iter().filter(|&p| self[p] == 9).collect() + } + + fn count_reachable_heights(&self, root: &Point) -> u64 { + self.walk_paths(root) + .into_iter() + .collect::>() + .len() + .try_into() + .unwrap() } - adjs.iter().filter(|&&p| map[p] == 9).copied().collect() -} -fn count_trails(map: &Map, root: &Point) -> u64 { - walk_paths(map, root) - .iter() - .collect::>() - .len() - .try_into() - .unwrap() + fn count_unique_trails(&self, root: &Point) -> u64 { + self.walk_paths(root).len().try_into().unwrap() + } } -fn count_unique_trails(map: &Map, root: &Point) -> u64 { - walk_paths(map, root).len().try_into().unwrap() +fn parse(input: &str) -> Map { + Map(input + .lines() + .map(|l| l.chars().map(|c| c.to_string().parse().unwrap()).collect()) + .collect()) } pub fn part1() { let map = parse(input()); - let n: u64 = find_height(&map, 0).map(|p| count_trails(&map, &p)).sum(); + let n: u64 = map + .find_height(0) + .map(|p| map.count_reachable_heights(&p)) + .sum(); println!("Day 10 Part 1: {}", n); } pub fn part2() { let map = parse(input()); - let n: u64 = find_height(&map, 0) - .map(|p| count_unique_trails(&map, &p)) + let n: u64 = map + .find_height(0) + .map(|p| map.count_unique_trails(&p)) .sum(); println!("Day 10 Part 2: {}", n); } @@ -157,34 +161,34 @@ mod test { #[test] fn test_count_trails() { let map = parse(TINY_INPUT); - assert_eq!(count_trails(&map, &Point(0, 0)), 1); + assert_eq!(map.count_reachable_heights(&Point(0, 0)), 1); let map = parse(INPUT_STR); - assert_eq!(count_trails(&map, &Point(0, 2)), 5); - assert_eq!(count_trails(&map, &Point(0, 4)), 6); - assert_eq!(count_trails(&map, &Point(2, 4)), 5); - assert_eq!(count_trails(&map, &Point(4, 6)), 3); - assert_eq!(count_trails(&map, &Point(5, 2)), 1); - assert_eq!(count_trails(&map, &Point(5, 5)), 3); - assert_eq!(count_trails(&map, &Point(6, 0)), 5); - assert_eq!(count_trails(&map, &Point(6, 6)), 3); - assert_eq!(count_trails(&map, &Point(7, 1)), 5); + assert_eq!(map.count_reachable_heights(&Point(0, 2)), 5); + assert_eq!(map.count_reachable_heights(&Point(0, 4)), 6); + assert_eq!(map.count_reachable_heights(&Point(2, 4)), 5); + assert_eq!(map.count_reachable_heights(&Point(4, 6)), 3); + assert_eq!(map.count_reachable_heights(&Point(5, 2)), 1); + assert_eq!(map.count_reachable_heights(&Point(5, 5)), 3); + assert_eq!(map.count_reachable_heights(&Point(6, 0)), 5); + assert_eq!(map.count_reachable_heights(&Point(6, 6)), 3); + assert_eq!(map.count_reachable_heights(&Point(7, 1)), 5); } #[test] fn test_count_unique_trails() { let map = parse(TINY_INPUT); - assert_eq!(count_unique_trails(&map, &Point(0, 0)), 16); + assert_eq!(map.count_unique_trails(&Point(0, 0)), 16); let map = parse(INPUT_STR); - assert_eq!(count_unique_trails(&map, &Point(0, 2)), 20); - assert_eq!(count_unique_trails(&map, &Point(0, 4)), 24); - assert_eq!(count_unique_trails(&map, &Point(2, 4)), 10); - assert_eq!(count_unique_trails(&map, &Point(4, 6)), 4); - assert_eq!(count_unique_trails(&map, &Point(5, 2)), 1); - assert_eq!(count_unique_trails(&map, &Point(5, 5)), 4); - assert_eq!(count_unique_trails(&map, &Point(6, 0)), 5); - assert_eq!(count_unique_trails(&map, &Point(6, 6)), 8); - assert_eq!(count_unique_trails(&map, &Point(7, 1)), 5); + assert_eq!(map.count_unique_trails(&Point(0, 2)), 20); + assert_eq!(map.count_unique_trails(&Point(0, 4)), 24); + assert_eq!(map.count_unique_trails(&Point(2, 4)), 10); + assert_eq!(map.count_unique_trails(&Point(4, 6)), 4); + assert_eq!(map.count_unique_trails(&Point(5, 2)), 1); + assert_eq!(map.count_unique_trails(&Point(5, 5)), 4); + assert_eq!(map.count_unique_trails(&Point(6, 0)), 5); + assert_eq!(map.count_unique_trails(&Point(6, 6)), 8); + assert_eq!(map.count_unique_trails(&Point(7, 1)), 5); } } -- 2.38.5