67 lines
No EOL
1.8 KiB
Rust
67 lines
No EOL
1.8 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use aoc::read_input;
|
|
use itertools::Itertools;
|
|
use linked_hash_map::LinkedHashMap;
|
|
|
|
fn hash_hash(string: &str) -> usize {
|
|
let mut current = 0;
|
|
for ch in string.bytes() {
|
|
current += ch as usize;
|
|
current *= 17;
|
|
current = current % 256;
|
|
}
|
|
|
|
current
|
|
}
|
|
|
|
struct LensBox<'a> {
|
|
content: LinkedHashMap<&'a str, usize>
|
|
}
|
|
|
|
impl <'a> LensBox<'a> {
|
|
fn new() -> LensBox<'a> {
|
|
LensBox {
|
|
content: LinkedHashMap::new()
|
|
}
|
|
}
|
|
|
|
fn remove(&mut self, label: &str) {
|
|
self.content.remove(label);
|
|
}
|
|
|
|
fn add(&mut self, label: &'a str, power: usize) {
|
|
*self.content.entry(label).or_insert(power) = power;
|
|
}
|
|
|
|
fn focus_power(&self, box_index: usize) -> usize {
|
|
self.content.iter().enumerate().fold(0, |a, (lens_index, (_, focus))| a + (box_index + 1) * (lens_index + 1) * *focus)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let input = read_input();
|
|
let input = input.split(',').collect_vec();
|
|
let result = input.iter().map(|str| hash_hash(str)).fold(0, |a,b| a+ b);
|
|
println!("Part 1: {result}");
|
|
|
|
let mut boxes = HashMap::new();
|
|
for instruction in input.iter() {
|
|
let index = instruction.find(|ch| ch == '=' || ch == '-').expect("Invalid instruction");
|
|
let label = &instruction[..index];
|
|
let box_index = hash_hash(label);
|
|
let lens_box = boxes.entry(box_index).or_insert_with(|| LensBox::new());
|
|
if &instruction[index..=index] == "-" {
|
|
lens_box.remove(label)
|
|
} else {
|
|
let power = instruction[(index + 1)..].parse().expect("Invalid instruction");
|
|
lens_box.add(label, power)
|
|
}
|
|
}
|
|
|
|
let part2 = (0..=256)
|
|
.filter_map(|n| Some(boxes.get(&n)?.focus_power(n)) )
|
|
.fold(0, |a, b| a + b);
|
|
|
|
println!("Part 2: {part2}");
|
|
} |