summaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-12-15 00:34:36 -0500
committerJesse Luehrs <doy@tozt.net>2023-12-15 00:34:36 -0500
commit2ad34fcc6e95ebcea0bf005eb58561f8bbe402f1 (patch)
tree11a9fd59bcd2fa18aa859f790b94ed2be09913ac /src/bin
parent8985dc2828c2afd2a41e338a4a25267081b21334 (diff)
downloadadvent-of-code-2ad34fcc6e95ebcea0bf005eb58561f8bbe402f1.tar.gz
advent-of-code-2ad34fcc6e95ebcea0bf005eb58561f8bbe402f1.zip
day 15
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/2023/day15.rs98
-rw-r--r--src/bin/2023/main.rs2
2 files changed, 100 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
+ );
+}
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),
}