From 2ad34fcc6e95ebcea0bf005eb58561f8bbe402f1 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 15 Dec 2023 00:34:36 -0500 Subject: day 15 --- src/bin/2023/day15.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/2023/main.rs | 2 ++ 2 files changed, 100 insertions(+) create mode 100644 src/bin/2023/day15.rs (limited to 'src/bin') diff --git a/src/bin/2023/day15.rs b/src/bin/2023/day15.rs new file mode 100644 index 0000000..3590938 --- /dev/null +++ b/src/bin/2023/day15.rs @@ -0,0 +1,98 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use advent_of_code::prelude::*; + +pub struct Todo; + +#[derive(Clone, Debug)] +struct LensBox { + lenses: Vec<(String, i64)>, +} + +impl LensBox { + fn new() -> Self { + Self { lenses: vec![] } + } + + fn insert(&mut self, label: String, focal_length: i64) { + if let Some(idx) = self.lenses.iter().position(|(s, _)| *s == label) { + self.lenses[idx] = (label, focal_length); + } else { + self.lenses.push((label, focal_length)); + } + } + + fn remove(&mut self, label: &str) { + if let Some(idx) = self.lenses.iter().position(|(s, _)| *s == label) { + self.lenses.remove(idx); + } + } +} + +fn hash(s: &str) -> usize { + let mut current = 0usize; + for c in s.bytes() { + current += usize::from(c); + current *= 17; + current %= 256; + } + current +} + +pub fn parse(fh: File) -> Result> { + Ok(parse::split(fh, b',').collect()) +} + +pub fn part1(ops: Vec) -> Result { + Ok(ops + .into_iter() + .map(|s| hash(&s)) + .sum::() + .try_into() + .unwrap()) +} + +pub fn part2(ops: Vec) -> Result { + let mut boxes = vec![LensBox::new(); 256]; + for op in ops { + if let Some(idx) = op.find('=') { + let label = &op[..idx]; + let lens_box = hash(label); + let focal_length: i64 = op[(idx + 1)..].parse().unwrap(); + boxes[lens_box].insert(label.to_string(), focal_length); + } else if op.ends_with('-') { + let label = &op[..(op.len() - 1)]; + let lens_box = hash(label); + boxes[lens_box].remove(label); + } + } + Ok(boxes + .into_iter() + .enumerate() + .map(|(box_num, lens_box)| { + lens_box + .lenses + .iter() + .enumerate() + .map(|(lens_num, (_, focal_length))| { + (i64::try_from(box_num).unwrap() + 1) + * (i64::try_from(lens_num).unwrap() + 1) + * focal_length + }) + .sum::() + }) + .sum()) +} + +#[test] +fn test() { + assert_eq!( + part1(parse(parse::data(2023, 15).unwrap()).unwrap()).unwrap(), + 497373 + ); + assert_eq!( + part2(parse(parse::data(2023, 15).unwrap()).unwrap()).unwrap(), + 259356 + ); +} diff --git a/src/bin/2023/main.rs b/src/bin/2023/main.rs index af0836a..31e55c5 100644 --- a/src/bin/2023/main.rs +++ b/src/bin/2023/main.rs @@ -25,6 +25,7 @@ mod day11; mod day12; mod day13; mod day14; +mod day15; // NEXT MOD #[paw::main] @@ -45,6 +46,7 @@ fn main(opt: Opt) -> Result<()> { 12 => advent_of_code::day!(2023, opt.day, opt.puzzle, day12), 13 => advent_of_code::day!(2023, opt.day, opt.puzzle, day13), 14 => advent_of_code::day!(2023, opt.day, opt.puzzle, day14), + 15 => advent_of_code::day!(2023, opt.day, opt.puzzle, day15), // NEXT PART _ => panic!("unknown day {}", opt.day), } -- cgit v1.2.3-54-g00ecf