Day 7
This commit is contained in:
parent
40b926347b
commit
585eefd437
1 changed files with 116 additions and 0 deletions
116
src/bin/day7.rs
Normal file
116
src/bin/day7.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use aoc_2024::{load, print_res};
|
||||||
|
use bstr::BString;
|
||||||
|
use color_eyre::eyre::Context;
|
||||||
|
|
||||||
|
type Parsed = Vec<(u64, Vec<u64>)>;
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn parsing(input: &BString) -> color_eyre::Result<Parsed> {
|
||||||
|
core::str::from_utf8(input)?
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let Some((result, values)) = line.split_once(':') else {
|
||||||
|
color_eyre::eyre::bail!("Missing `:` in '{line}'");
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
result.parse().with_context(|| "could not parse result")?,
|
||||||
|
values
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|n| n.parse().with_context(|| "could not parse value `{n}`"))
|
||||||
|
.collect::<Result<_, _>>()
|
||||||
|
.with_context(|| "could not parse values")?,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn part1(input: Parsed) {
|
||||||
|
let mut total_calibration_result = 0;
|
||||||
|
|
||||||
|
for (result, values) in input {
|
||||||
|
let mut totals = vec![values[0]];
|
||||||
|
|
||||||
|
for v in &values[1..] {
|
||||||
|
let mut new = Vec::with_capacity(totals.len() * 2);
|
||||||
|
for total in totals {
|
||||||
|
let p = total + v;
|
||||||
|
if p <= result {
|
||||||
|
new.push(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
let m = total * v;
|
||||||
|
if m <= result {
|
||||||
|
new.push(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totals = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
if totals.contains(&result) {
|
||||||
|
total_calibration_result += result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_res!("Total calibration result: {total_calibration_result}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn part2(input: Parsed) {
|
||||||
|
let mut total_calibration_result = 0;
|
||||||
|
|
||||||
|
for (result, values) in input {
|
||||||
|
let mut totals = vec![values[0]];
|
||||||
|
|
||||||
|
for v in &values[1..] {
|
||||||
|
let mut new = Vec::with_capacity(totals.len() * 3);
|
||||||
|
for total in totals {
|
||||||
|
let p = total + v;
|
||||||
|
if p <= result {
|
||||||
|
new.push(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
let m = total * v;
|
||||||
|
if m <= result {
|
||||||
|
new.push(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = total * 10u64.pow(v.ilog10() + 1) + v;
|
||||||
|
if c <= result {
|
||||||
|
new.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totals = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
if totals.contains(&result) {
|
||||||
|
total_calibration_result += result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_res!("Total calibration result: {total_calibration_result}")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() -> color_eyre::Result<()> {
|
||||||
|
let context = load()?;
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let parsed = parsing(&context.input)?;
|
||||||
|
let elapsed = humantime::format_duration(start.elapsed());
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
if context.part == 1 {
|
||||||
|
part1(parsed);
|
||||||
|
} else {
|
||||||
|
part2(parsed);
|
||||||
|
}
|
||||||
|
let elapsed_part = humantime::format_duration(start.elapsed());
|
||||||
|
|
||||||
|
println!(" Parsing: {elapsed}");
|
||||||
|
println!(" Solving: {elapsed_part}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue