Untitled
unknown
rust
a year ago
1.9 kB
22
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.get_sum_of_values();
(ans, now.elapsed())
}
#[derive(Debug, Clone)]
struct Stones {
stones: HashMap<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 = line_vals.iter().copied().counts();
Self {
stones,
cache: FxHashMap::default(),
}
}
fn blink(&mut self) {
let mut new_stones = HashMap::default();
for (val, amount) in self.stones.iter() {
let (next_val, split_val) = if let Some(cached) = self.cache.get(val) {
*cached
} else {
let result = blink(*val);
self.cache.insert(*val, result);
result
};
*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;
}
fn get_sum_of_values(&self) -> usize {
self.stones.iter().map(|(_, amount)| amount).sum()
}
}
fn blink(val: usize) -> (usize, Option<usize>) {
if val == 0 {
return (1, None);
} else {
let val_str = val.to_string();
if val_str.len() % 2 == 0 {
let first_half = &val_str[..val_str.len() / 2].parse().unwrap();
let second_half = &val_str[val_str.len() / 2..].parse().unwrap();
return (*first_half, Some(*second_half));
} else {
return (val * 2024, None);
}
}
}Editor is loading...