Had to take a couple days off, but this was a nice one to come back to. Will have to find some time today to go back and do one or two of the 3 that I missed. I don't have much to say about this one - I had an idea almost immediately and it worked out without much struggle. There's probably some cleaner ways to write parts of this, but I'm not too disappointed with how it turned out.
https://github.com/capitalpb/advent_of_code_2023/blob/main/src/solvers/day15.rs
use crate::Solver;
use std::collections::HashMap;
#[derive(Debug)]
struct Lens {
label: String,
focal_length: u32,
}
fn hash_algorithm(input: &str) -> u32 {
input
.chars()
.fold(0, |acc, ch| (acc + ch as u32) * 17 % 256)
}
pub struct Day15;
impl Solver for Day15 {
fn star_one(&self, input: &str) -> String {
input
.trim_end()
.split(',')
.map(hash_algorithm)
.sum::()
.to_string()
}
fn star_two(&self, input: &str) -> String {
let mut boxes: HashMap> = HashMap::new();
for instruction in input.trim_end().split(',') {
let (label, focal_length) = instruction
.split_once(|ch| char::is_ascii_punctuation(&ch))
.unwrap();
let box_number = hash_algorithm(label);
let lenses = boxes.entry(box_number).or_insert(vec![]);
if focal_length == "" {
lenses.retain(|lens| lens.label != label);
continue;
}
let new_lens = Lens {
label: label.to_string(),
focal_length: focal_length.parse().unwrap(),
};
if let Some(lens_index) = lenses.iter().position(|lens| lens.label == new_lens.label) {
lenses[lens_index].focal_length = new_lens.focal_length;
} else {
lenses.push(new_lens);
}
}
boxes
.iter()
.map(|(box_number, lenses)| {
lenses
.iter()
.enumerate()
.map(|(lens_index, lens)| {
(box_number + 1) * (lens_index as u32 + 1) * lens.focal_length
})
.sum::()
})
.sum::()
.to_string()
}
}
I've had the damn song stuck in my head since I saw this post.