diff --git a/2023/src/bin/day15.rs b/2023/src/bin/day15.rs index 312414e..efeb6bb 100644 --- a/2023/src/bin/day15.rs +++ b/2023/src/bin/day15.rs @@ -3,32 +3,51 @@ extern crate test; use aoc2023::{boilerplate, common::*}; const DAY: usize = 15; -type I = u32; +type I = usize; type Parsed<'a> = impl Iterator + Clone; fn parse_input(raw: &str) -> Parsed { raw.trim_end_matches('\n').split(',') } -fn hash(s: &str) -> I { - s.bytes().fold(0, |acc, b| (acc + b as I) * 17 & 255) +fn hash(s: &[u8]) -> I { + s.iter().fold(0, |acc, &b| (acc + b as I) * 17 & 255) } fn part1(parsed: &Parsed) -> I { - parsed.clone().map(hash).inspect(|n| println!("{n}")).sum() + parsed.clone().map(|s| hash(s.as_bytes())).sum() } fn part2(parsed: &Parsed) -> I { - unimplemented!() + let mut boxes: Vec> = vec![vec![]; 256]; + for s in parsed.clone() { + match s.as_bytes() { + [label @ .., b'-'] => { + let hash = hash(&label); + if let Some(p) = boxes[hash].iter().position(|(l, _)| l == &label) { + boxes[hash].remove(p); + } + } + [label @ .., b'=', focal_strength] => { + let hash = hash(&label); + match boxes[hash].iter().position(|(l, _)| l == &label) { + Some(p) => boxes[hash][p] = (&label, focal_strength - b'0'), + None => boxes[hash].push((&label, focal_strength - b'0')), + } + } + _ => unreachable!(), + } + } + boxes.into_iter().zip(1..).flat_map(|(b, i)| b.into_iter().zip(1..).map(move |((_, f), j)| i * j * f as I)).sum() } boilerplate! { TEST_INPUT == "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7" for tests: { part1: { TEST_INPUT => 1320 }, - part2: { TEST_INPUT => 0 }, + part2: { TEST_INPUT => 145 }, }, bench1 == 510273, - bench2 == 0, + bench2 == 212449, bench_parse: |i: &Parsed| i.clone().count() => 4000, }