mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 17:45:02 +01:00
optimize d7p2
This commit is contained in:
parent
b1e24f6e1e
commit
3e9ff4ded0
1 changed files with 78 additions and 1 deletions
|
|
@ -14,6 +14,8 @@ helper::define_variants! {
|
||||||
part2 {
|
part2 {
|
||||||
basic => crate::part2,sample_count=500;
|
basic => crate::part2,sample_count=500;
|
||||||
no_string_fmt => crate::part2_no_string_fmt,sample_count=1000;
|
no_string_fmt => crate::part2_no_string_fmt,sample_count=1000;
|
||||||
|
order => crate::part2_order,sample_count=1000;
|
||||||
|
parsing => crate::part2_parsing,sample_count=5000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +129,81 @@ fn part2_no_string_fmt(input: &str) -> u64 {
|
||||||
total
|
total
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn part2_order(input: &str) -> u64 {
|
||||||
|
let mut total = 0;
|
||||||
|
for line in input.lines() {
|
||||||
|
let (result, values) = line.split_once(": ").unwrap();
|
||||||
|
let result = parse_unwrap(result);
|
||||||
|
let values = values
|
||||||
|
.split(" ")
|
||||||
|
.map(|val| (val, parse_unwrap(val)))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
fn does_work(values: &[(&str, u64)], result: u64) -> bool {
|
||||||
|
if values.len() == 1 {
|
||||||
|
return values[0].1 == result;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (l_str, l) = *values.last().unwrap();
|
||||||
|
let next = &values[..(values.len() - 1)];
|
||||||
|
let thousand = 10_u64.pow(l_str.len() as u32);
|
||||||
|
|
||||||
|
let concat_works = result % thousand == l;
|
||||||
|
let mul_works = result % l == 0;
|
||||||
|
let sub_works = l <= result;
|
||||||
|
|
||||||
|
// Concat is the least common, so doing it first helps remove the most possibilities.
|
||||||
|
false
|
||||||
|
|| (concat_works && does_work(next, result / thousand))
|
||||||
|
|| (mul_works && does_work(next, result / l))
|
||||||
|
|| (sub_works && does_work(next, result - l))
|
||||||
|
}
|
||||||
|
|
||||||
|
if does_work(&values, result) {
|
||||||
|
total += result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2_parsing(input: &str) -> u64 {
|
||||||
|
let mut total = 0;
|
||||||
|
|
||||||
|
let mut values = Vec::new();
|
||||||
|
|
||||||
|
for line in input.lines() {
|
||||||
|
values.clear();
|
||||||
|
let (result, values_str) = line.split_once(": ").unwrap();
|
||||||
|
let result = parse_unwrap(result);
|
||||||
|
values.extend(values_str.split(' ').map(|val| (val, parse_unwrap(val))));
|
||||||
|
|
||||||
|
fn does_work(values: &[(&str, u64)], result: u64) -> bool {
|
||||||
|
if values.len() == 1 {
|
||||||
|
return values[0].1 == result;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (l_str, l) = *values.last().unwrap();
|
||||||
|
let next = &values[..(values.len() - 1)];
|
||||||
|
let thousand = 10_u64.pow(l_str.len() as u32);
|
||||||
|
|
||||||
|
let concat_works = result % thousand == l;
|
||||||
|
let mul_works = result % l == 0;
|
||||||
|
let sub_works = l <= result;
|
||||||
|
|
||||||
|
// Concat is the least common, so doing it first helps remove the most possibilities.
|
||||||
|
false
|
||||||
|
|| (concat_works && does_work(next, result / thousand))
|
||||||
|
|| (mul_works && does_work(next, result / l))
|
||||||
|
|| (sub_works && does_work(next, result - l))
|
||||||
|
}
|
||||||
|
|
||||||
|
if does_work(&values, result) {
|
||||||
|
total += result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total
|
||||||
|
}
|
||||||
|
|
||||||
helper::tests! {
|
helper::tests! {
|
||||||
day07 Day07;
|
day07 Day07;
|
||||||
part1 {
|
part1 {
|
||||||
|
|
@ -135,7 +212,7 @@ helper::tests! {
|
||||||
}
|
}
|
||||||
part2 {
|
part2 {
|
||||||
small => 11387;
|
small => 11387;
|
||||||
default => 0;
|
default => 146111650210682;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
helper::benchmarks! {}
|
helper::benchmarks! {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue