From a7416ed0560a325a67bd4616a65a23115c123047 Mon Sep 17 00:00:00 2001 From: Jan-Bulthuis Date: Sat, 7 Dec 2024 15:48:34 +0100 Subject: [PATCH] day7 fast --- aoc_2024/src/day7.rs | 45 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/aoc_2024/src/day7.rs b/aoc_2024/src/day7.rs index eb4ea98..678b16a 100644 --- a/aoc_2024/src/day7.rs +++ b/aoc_2024/src/day7.rs @@ -23,19 +23,19 @@ fn parse(input: &str) -> Input { fn part1(input: &Input) -> usize { input .iter() - .filter(|v| part1_test(v.1[0], v.0, &v.1[1..])) + .filter(|v| part1_test(v.1[0] as i64, v.0 as i64, &v.1[1..])) .fold(0, |acc, v| acc + v.0 as usize) } -fn part1_test(curr: u64, target: u64, numbers: &[u64]) -> bool { - if curr > target { - false - } else if numbers.is_empty() { - curr == target +fn part1_test(target: i64, remaining: i64, numbers: &[u64]) -> bool { + if numbers.is_empty() { + remaining == target } else { - let num = numbers[0]; - let rest = &numbers[1..]; - part1_test(curr + num, target, rest) || part1_test(curr * num, target, rest) + let num = numbers[numbers.len() - 1] as i64; + let rest = &numbers[0..numbers.len() - 1]; + let mul = remaining % num == 0 && part1_test(target, remaining / num, rest); + let add = part1_test(target, remaining - num, rest); + mul || add } } @@ -43,26 +43,21 @@ fn part1_test(curr: u64, target: u64, numbers: &[u64]) -> bool { fn part2(input: &Input) -> usize { input .iter() - .filter(|v| part2_test(v.1[0], v.0, &v.1[1..])) + .filter(|v| part2_test(v.1[0] as i64, v.0 as i64, &v.1[1..])) .fold(0, |acc, v| acc + v.0 as usize) } -fn concat(a: u64, b: u64) -> u64 { - let digits = b.ilog10() + 1; - a * 10u64.pow(digits) + b -} - -fn part2_test(curr: u64, target: u64, numbers: &[u64]) -> bool { - if curr > target { - false - } else if numbers.is_empty() { - curr == target +fn part2_test(target: i64, remaining: i64, numbers: &[u64]) -> bool { + if numbers.is_empty() { + remaining == target } else { - let num = numbers[0]; - let rest = &numbers[1..]; - part2_test(curr + num, target, rest) - || part2_test(curr * num, target, rest) - || part2_test(concat(curr, num), target, rest) + let num = numbers[numbers.len() - 1] as i64; + let rest = &numbers[0..numbers.len() - 1]; + let mul = remaining % num == 0 && part2_test(target, remaining / num, rest); + let pow = 10i64.pow(num.ilog10() + 1); + let con = remaining % pow == num && part2_test(target, remaining / pow, rest); + let add = part2_test(target, remaining - num, rest); + mul || con || add } }