This commit is contained in:
Quentin Boyer 2024-12-11 23:17:50 +01:00
parent b443e3b01c
commit 7e550fd322

87
src/bin/day11.rs Normal file
View file

@ -0,0 +1,87 @@
use std::{collections::HashMap, time::Instant};
use aoc_2024::{load, print_res};
use bstr::BString;
type Parsed = Vec<u64>;
#[inline(never)]
pub fn parsing(input: &BString) -> color_eyre::Result<Parsed> {
std::str::from_utf8(input)?
.split_whitespace()
.map(|n| n.parse().map_err(Into::into))
.collect()
}
struct StoneMemo {
memo: HashMap<(u64, u8), u64>,
}
impl StoneMemo {
pub fn new() -> Self {
Self {
memo: HashMap::new(),
}
}
pub fn calculate(&mut self, stone: u64, steps: u8) -> u64 {
if steps == 0 {
return 1;
}
if let Some(&v) = self.memo.get(&(stone, steps)) {
return v;
}
let result = if stone == 0 {
self.calculate(1, steps - 1)
} else if stone.ilog10() % 2 == 1 {
let digits = (stone.ilog10() + 1) / 2;
let high = stone / 10u64.pow(digits);
let low = stone % 10u64.pow(digits);
self.calculate(high, steps - 1) + self.calculate(low, steps - 1)
} else {
self.calculate(stone * 2024, steps - 1)
};
self.memo.insert((stone, steps), result);
result
}
}
#[inline(never)]
pub fn part1(input: Parsed) {
let mut memo = StoneMemo::new();
let result: u64 = input.iter().map(|&n| memo.calculate(n, 25)).sum();
print_res!("Number of stones: {result}")
}
#[inline(never)]
pub fn part2(input: Parsed) {
let mut memo = StoneMemo::new();
let result: u64 = input.iter().map(|&n| memo.calculate(n, 75)).sum();
print_res!("Number of stones: {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(())
}