-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path15.rs
71 lines (61 loc) · 1.63 KB
/
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
65
66
67
68
69
70
71
#![feature(test)]
use indexmap::IndexMap;
use regex::Regex;
type Input = Vec<Step>;
#[derive(Debug)]
struct Step {
raw: String,
label: String,
op: Operation,
}
#[derive(Debug, Clone, Copy)]
enum Operation {
Remove,
Insert(u8),
}
fn setup(input: &str) -> Input {
let re = Regex::new(r"^([^=-]+)(-|=(\d+))$").unwrap();
input
.split(',')
.map(|step| {
let step = step.trim();
let caps = re.captures(step).unwrap();
Step {
raw: step.into(),
label: caps[1].into(),
op: match caps.get(3) {
Some(focal_length) => Operation::Insert(focal_length.as_str().parse().unwrap()),
None => Operation::Remove,
},
}
})
.collect()
}
fn hash(input: &str) -> usize {
input
.bytes()
.fold(0, |acc, b| (acc + b as usize) * 17 % 256)
}
fn part1(input: &Input) -> usize {
input.iter().map(|s| hash(&s.raw)).sum()
}
fn part2(input: &Input) -> usize {
let mut boxes = vec![IndexMap::new(); 256];
for step in input {
let bx = &mut boxes[hash(&step.label)];
match step.op {
Operation::Remove => bx.shift_remove(&step.label),
Operation::Insert(focal_length) => bx.insert(&step.label, focal_length),
};
}
boxes
.into_iter()
.enumerate()
.flat_map(|(i, bx)| {
bx.into_values()
.enumerate()
.map(move |(j, focal_length)| (i + 1) * (j + 1) * focal_length as usize)
})
.sum()
}
aoc::main!(2023, 15, ex: 1);