Day 11
This commit is contained in:
parent
b443e3b01c
commit
7e550fd322
1 changed files with 87 additions and 0 deletions
87
src/bin/day11.rs
Normal file
87
src/bin/day11.rs
Normal 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(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue