Untitled
unknown
rust
4 months ago
1.9 kB
24
Indexable
fn solve(stones: &Stones, iters: usize) -> (usize, Duration) { let now = Instant::now(); let mut stones = stones.clone(); for i in 1..=iters { stones.blink(); } let ans = stones.stones.values().sum(); (ans, now.elapsed()) } #[derive(Debug, Clone)] struct Stones { stones: FxHashMap<usize, usize>, cache: FxHashMap<usize, (usize, Option<usize>)>, } impl Stones { fn from_str(line: &str) -> Self { let line_vals = line .split(' ') .map(|x| x.parse().unwrap()) .collect::<Vec<usize>>(); let stones = counts(line_vals.iter().copied()); Self { stones, cache: FxHashMap::default(), } } fn blink(&mut self) { let mut new_stones = FxHashMap::default(); for (&val, &amount) in &self.stones { let (next_val, split_val) = *self.cache.entry(val).or_insert_with(|| blink(val)); *new_stones.entry(next_val).or_insert(0) += amount; if let Some(split_val) = split_val { *new_stones.entry(split_val).or_insert(0) += amount; } } self.stones = new_stones.into_iter().collect(); } } fn blink(val: usize) -> (usize, Option<usize>) { if val == 0 { return (1, None); } else { let len = (val as f64).log10().floor() as usize + 1; if len % 2 == 0 { let mid = len / 2; let divisor = 10_usize.pow(mid as u32); let first_half = val / divisor; let second_half = val % divisor; return (first_half, Some(second_half)); } else { return (val * 2024, None); } } } fn counts<I>(iter: I) -> FxHashMap<I::Item, usize> where I: Iterator + Sized, I::Item: Eq + std::hash::Hash, { let mut counts = FxHashMap::default(); iter.for_each(|item| *counts.entry(item).or_default() += 1); counts }
Editor is loading...
Leave a Comment