Day 3
This commit is contained in:
parent
2be9fa8aba
commit
6fd57bcc6d
1 changed files with 115 additions and 0 deletions
115
src/bin/day3.rs
Normal file
115
src/bin/day3.rs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use aoc_2025::{load, print_res};
|
||||
use bstr::{BStr, BString, ByteSlice};
|
||||
|
||||
type Parsed<'a> = Vec<Bank<'a>>;
|
||||
|
||||
const MAX_JOLT_LEN: usize = 12;
|
||||
|
||||
pub struct Bank<'a> {
|
||||
values: &'a BStr,
|
||||
joltage_cache: [Vec<usize>; MAX_JOLT_LEN],
|
||||
}
|
||||
|
||||
impl<'a> Bank<'a> {
|
||||
fn max_joltage_from(&mut self, len: usize, from: usize) -> usize {
|
||||
assert!(len <= MAX_JOLT_LEN);
|
||||
assert!(len > 0);
|
||||
|
||||
if self.joltage_cache[len - 1][from] != 0 {
|
||||
return self.joltage_cache[len - 1][from];
|
||||
}
|
||||
|
||||
let &largest_hi = self
|
||||
.values
|
||||
.iter()
|
||||
.take(self.values.len() - (len - 1))
|
||||
.skip(from)
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
if len == 1 {
|
||||
let val = (largest_hi - b'0') as usize;
|
||||
self.joltage_cache[len - 1][from] = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
let mut max = 0;
|
||||
|
||||
for (i, _) in self
|
||||
.values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.take(self.values.len() - (len - 1))
|
||||
.skip(from)
|
||||
.filter(|&(_, &v)| v == largest_hi)
|
||||
{
|
||||
let largest_low = self.max_joltage_from(len - 1, i + 1);
|
||||
|
||||
let joltage = (largest_hi - b'0') as usize * 10usize.pow(len as u32 - 1) + largest_low;
|
||||
max = max.max(joltage);
|
||||
}
|
||||
|
||||
self.joltage_cache[len - 1][from] = max;
|
||||
max
|
||||
}
|
||||
|
||||
pub fn max_joltage(&mut self, len: usize) -> usize {
|
||||
self.max_joltage_from(len, 0)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn parsing(input: &BString) -> color_eyre::Result<Parsed<'_>> {
|
||||
Ok(input
|
||||
.lines()
|
||||
.map(|v| Bank {
|
||||
values: v.as_bstr(),
|
||||
joltage_cache: std::array::from_fn(|_| vec![0; v.len()]),
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn part1(input: Parsed) {
|
||||
let mut joltage_sum = 0;
|
||||
|
||||
for mut bank in input {
|
||||
joltage_sum += bank.max_joltage(2);
|
||||
}
|
||||
|
||||
print_res!("Maximum total joltage: {joltage_sum}");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn part2(input: Parsed) {
|
||||
let mut joltage_sum = 0;
|
||||
|
||||
for mut bank in input {
|
||||
joltage_sum += bank.max_joltage(12);
|
||||
}
|
||||
|
||||
print_res!("Maximum total joltage: {joltage_sum}");
|
||||
}
|
||||
|
||||
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