From 0a5e5c8798fae491b2107c0d707b2090a19e5dd3 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Tue, 9 Dec 2025 22:45:33 -0800 Subject: [PATCH] day10: small performance boost --- src/day10.rs | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/day10.rs b/src/day10.rs index 0d33b39..8474e41 100644 --- a/src/day10.rs +++ b/src/day10.rs @@ -1,7 +1,6 @@ -use std::{collections::BinaryHeap, iter::repeat_n}; +use std::{collections::BinaryHeap, hash::Hash, iter::repeat_n}; use aoc_runner_derive::{aoc, aoc_generator}; -use itertools::Itertools; use regex::Regex; #[derive(Clone, Debug, Default)] @@ -54,6 +53,19 @@ struct Machine<'a> { lights: Vec, } +impl<'a> Eq for Machine<'a> {} +impl<'a> PartialEq for Machine<'a> { + fn eq(&self, other: &Self) -> bool { + self.lights == other.lights + } +} + +impl<'a> Hash for Machine<'a> { + fn hash(&self, state: &mut H) { + self.lights.hash(state) + } +} + impl<'a> Machine<'a> { /// Get the state after pressing `button`, returns None if the state is as desired fn press(&self, button: usize) -> Option { @@ -85,7 +97,7 @@ impl<'a> Machine<'a> { #[derive(Debug, Clone)] struct PressSet<'a> { machine: Machine<'a>, - presses: Vec, + presses: usize, } // NOTE: All compares are reversed so our max heap becomes a min heap @@ -93,41 +105,41 @@ impl<'a> Eq for PressSet<'a> {} impl<'a> PartialEq for PressSet<'a> { fn eq(&self, other: &Self) -> bool { - other.presses.len().eq(&self.presses.len()) + other.presses.eq(&self.presses) } } impl<'a> PartialOrd for PressSet<'a> { fn partial_cmp(&self, other: &Self) -> Option { - other.presses.len().partial_cmp(&self.presses.len()) + Some(self.cmp(other)) } } impl<'a> Ord for PressSet<'a> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - other.presses.len().cmp(&self.presses.len()) + other.presses.cmp(&self.presses) } } -fn find_best<'a>(md: &'a MachineDefinition) -> Vec { +fn find_best(md: &MachineDefinition) -> usize { let m = md.create(); let mut to_check = BinaryHeap::new(); + for next in m.next_states() { if let Some(new_m) = next.1 { to_check.push(PressSet { - presses: vec![next.0], + presses: 1, machine: new_m.clone(), }) } else { // what we found a solution on the first move? - return vec![next.0]; + return 1; } } while let Some(candidate) = to_check.pop() { let cm = candidate.machine.clone(); for next in cm.next_states() { - let mut presses = candidate.presses.clone(); - presses.push(next.0); + let presses = candidate.presses + 1; if let Some(new_m) = next.1 { to_check.push(PressSet { presses, @@ -147,17 +159,17 @@ fn parse(input: &str) -> Vec { } #[aoc(day10, part1)] -fn part1(input: &Vec) -> u64 { +fn part1(input: &[MachineDefinition]) -> u64 { input - .into_iter() - .map(|md| find_best(md)) + .iter() + .map(find_best) // .inspect(|sol| println!(" [{sol:?}]")) - .map(|sol| sol.len() as u64) + .map(|sol| sol as u64) .sum() } #[aoc(day10, part2)] -fn part2(input: &Vec) -> u64 { +fn part2(input: &[MachineDefinition]) -> u64 { 0 } @@ -178,7 +190,7 @@ mod tests { } #[rstest] - #[case(EXAMPLE, 0)] + #[case(EXAMPLE, 33)] fn part2_example(#[case] input: &str, #[case] expected: u64) { assert_eq!(part2(&parse(input)), expected); }