summaryrefslogtreecommitdiffstats
path: root/src/bin/2023/day15.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/2023/day15.rs')
-rw-r--r--src/bin/2023/day15.rs98
1 files changed, 98 insertions, 0 deletions
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<Vec<String>> {
+ Ok(parse::split(fh, b',').collect())
+}
+
+pub fn part1(ops: Vec<String>) -> Result<i64> {
+ Ok(ops
+ .into_iter()
+ .map(|s| hash(&s))
+ .sum::<usize>()
+ .try_into()
+ .unwrap())
+}
+
+pub fn part2(ops: Vec<String>) -> Result<i64> {
+ 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::<i64>()
+ })
+ .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
+ );
+}