-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-15.rs
64 lines (52 loc) · 1.79 KB
/
day-15.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::array;
use aoc_2023::aoc;
const INPUT: &str = include_str!("day-15.txt");
#[allow(dead_code)]
const INPUT_EX: &str = "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7";
aoc! {
struct Day15<'a> {
words: Vec<&'a str>
}
self(input = INPUT) {
Ok(Self { words: input.trim().split(',').collect() })
}
1 part1 usize {
Ok(self.words.iter().copied().map(hash).sum())
}
2 part2 usize {
let mut boxes: [_; 256] = array::from_fn(|_| Vec::<(&str, u8)>::new());
for s in self.words.iter() {
if let Some(lens) = s.strip_suffix('-') {
let hash = hash(lens);
let bx = &mut boxes[hash];
if let Some(i) = find_lens(bx, lens) {
bx.remove(i);
}
} else {
let (lens, focal) = s.split_once('=').ok_or_else(|| format!("couldn't split {s}"))?;
let flen: u8 = focal.parse().map_err(|_| "parse error")?;
let hash = hash(lens);
let bx = &mut boxes[hash];
if let Some(i) = find_lens(bx, lens) {
bx[i].1 = flen;
} else {
bx.push((lens, flen));
}
}
}
Ok(boxes.iter().enumerate().map(|(i, bx)| {
let i = i + 1;
bx.iter().enumerate().map(|(j, (_, flen))| i * (j + 1) * *flen as usize).sum::<usize>()
}).sum())
}
INPUT_EX { 1 part1 = 1320, 2 part2 = 145 }
INPUT { 1 part1 = 517315, 2 part2 = 247763 }
}
fn hash(s: &str) -> usize {
s.as_bytes()
.iter()
.fold(0_u8, |hash, &b| hash.wrapping_add(b).wrapping_mul(17)) as usize
}
fn find_lens(v: &[(&str, u8)], s: &str) -> Option<usize> {
v.iter().position(|(s2, _)| &s == s2)
}