From db70ca7fa220d0320b47036e7aa38273645acd18 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 2 Dec 2024 08:31:59 -0500 Subject: [PATCH] Day 2 Clean Up, Util --- advent_core/src/day.rs | 8 +++---- utils/src/misc.rs | 51 +++++++++++++++++++++++++++++++++++++++++ years/2024/src/day_2.rs | 41 ++++++++++----------------------- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/advent_core/src/day.rs b/advent_core/src/day.rs index e0c1f9f..062596c 100644 --- a/advent_core/src/day.rs +++ b/advent_core/src/day.rs @@ -74,11 +74,11 @@ pub trait Day { _ => panic!("Invalid part number"), }; println!( - "Day {} Part {}: {} ({}ms)", + "Day {} Part {}: {} ({:?}ms)", Self::DAY, part, solution.as_ref().unwrap_or(&"Not implemented".to_string()), - instant.elapsed().as_millis() + instant.elapsed() ); solution } @@ -97,10 +97,10 @@ pub trait Day { _ => panic!("Invalid part number"), }; println!( - "{extra_indent} Part {}: {} ({}ms)", + "{extra_indent} Part {}: {} ({:?}ms)", part, solution.as_ref().unwrap_or(&"Not implemented".to_string()), - part_time.elapsed().as_millis() + part_time.elapsed() ); } } diff --git a/utils/src/misc.rs b/utils/src/misc.rs index d9ec7f4..37e3b57 100644 --- a/utils/src/misc.rs +++ b/utils/src/misc.rs @@ -1,3 +1,4 @@ +use core::ops::Range; use std::{collections::HashMap, hash::Hash}; pub fn counts(l: impl Iterator) -> HashMap { @@ -10,3 +11,53 @@ pub fn counts(l: impl Iterator) -> HashMap, enforce_one_way: bool, allow_eq: bool) -> FollowRangeResult { + if l.len() < 2 { + FollowRangeResult::ListTooShort + } else { + let first_diff = l[1] - l[0]; + if diff_range.contains(&first_diff) { + let mut ordering = FollowRangeResult::Fluctuates; + + let failing_pair = l.windows(2).skip(1).find_map(|w| { + let (x, y) = (w[0], w[1]); + let diff = y - x; + if diff_range.contains(&diff) && (allow_eq || diff != 0) { + if ordering == FollowRangeResult::Fluctuates && diff != 0 { + ordering = if diff < 0 { FollowRangeResult::Decreasing } else { FollowRangeResult::Increasing }; + None + } else if enforce_one_way && (ordering == FollowRangeResult::Increasing && diff < 0) || (ordering == FollowRangeResult::Decreasing && diff > 0) { + Some((x, y)) + } else { + None + } + } else { + Some((x, y)) + } + }); + + match failing_pair { + Some((x, y)) => FollowRangeResult::InvalidPair(x, y), + None => ordering + } + } else { + FollowRangeResult::InvalidPair(l[0], l[1]) + } + } +} + +pub fn all_combos_remove_one(l: &[T]) -> impl Iterator> { + (0..l.len()).map(|exclude| { + l.iter().enumerate().filter_map(move |(i, e)| Some(e).filter(|_| i != exclude)) + }) +} diff --git a/years/2024/src/day_2.rs b/years/2024/src/day_2.rs index 7f6a4a5..2ba69e8 100644 --- a/years/2024/src/day_2.rs +++ b/years/2024/src/day_2.rs @@ -1,26 +1,17 @@ use advent_core::{Day, day_stuff, ex_for_day}; +use utils::misc::{all_combos_remove_one, follows_diff_range, FollowRangeResult}; pub struct Day2; -fn line_valid(line: &[u64]) -> bool { - let mut increasing: Option = None; - line.windows(2).all(|w| { - let (x, y) = (w[0], w[1]); - if x == y || x.abs_diff(y) > 3 { - false - } else if let Some(increasing) = increasing { - !((increasing && y <= x) || (!increasing && x <= y)) - } else { - increasing = Some(x < y); - true - } - }) +fn line_valid(line: &[i64]) -> bool { + let res = follows_diff_range(line, -3..4, true, false); + matches!(res, FollowRangeResult::Increasing | FollowRangeResult::Decreasing) } impl Day for Day2 { - day_stuff!(2, "2", "4", Vec>); + day_stuff!(2, "2", "4", Vec>); fn part_1(input: Self::Input) -> Option { Some(input.into_iter().filter(|v| line_valid(&v)).count().to_string()) @@ -28,24 +19,16 @@ impl Day for Day2 { fn part_2(input: Self::Input) -> Option { Some(input.into_iter().filter(|line| { - let valid = line_valid(&line); - if valid { - true - } else { - (0..line.len()).any(|ie| { - let v = line.iter() - .enumerate() - .filter(|(i, _)| *i != ie) - .map(|(_, e)| *e) - .collect::>(); - - line_valid(&v) - }) - } + line_valid(&line) || + all_combos_remove_one(line) + .any(|combo| { + let v = combo.map(|x| *x).collect::>(); + line_valid(&v) + }) }).count().to_string()) } fn parse_input(input: &str) -> Self::Input { - input.split('\n').map(|l| l.split_ascii_whitespace().map(|x| x.parse::().unwrap()).collect()).collect() + input.split('\n').map(|l| l.split_ascii_whitespace().map(|x| x.parse::().unwrap()).collect()).collect() } } -- 2.51.2