Untitled
unknown
rust
a year ago
1.9 kB
28
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