-
Notifications
You must be signed in to change notification settings - Fork 0
/
day15.rs
101 lines (90 loc) · 2.58 KB
/
day15.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::data::load;
fn ascii_hash(s: &str) -> usize {
s.trim()
.chars()
.map(|c| c as u8 as usize)
.fold(0, |a, b| ((a + b) * 17) % 256)
}
pub fn puzzle_1(input: &str) -> usize {
input.split(',').map(ascii_hash).sum()
}
#[derive(Debug, Clone, Copy)]
struct Lens<'a> {
label: &'a str,
focal_len: Option<usize>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Operation {
D,
E,
}
impl From<&char> for Operation {
fn from(value: &char) -> Self {
match value {
'-' => Operation::D,
'=' => Operation::E,
_ => panic!("Unkown op: {}", value),
}
}
}
fn calc_focussing_power(boxes: &[Vec<Lens>]) -> usize {
boxes
.iter()
.enumerate()
.map(|(b_idx, b)| {
b.iter()
.enumerate()
.map(|(lens_idx, lens)| (b_idx + 1) * (lens_idx + 1) * lens.focal_len.unwrap())
.sum::<usize>()
})
.sum()
}
fn parse_step(step: &str) -> (Lens, Operation) {
if step.contains('-') {
return (
Lens {
label: step.split('-').collect::<Vec<_>>()[0],
focal_len: None,
},
Operation::D,
);
}
let split = step.split('=').collect::<Vec<_>>();
let label = split[0];
let focal_len = Some(split[1].parse::<usize>().unwrap());
(Lens { label, focal_len }, Operation::E)
}
pub fn puzzle_2(input: &str) -> usize {
let mut boxes: Vec<Vec<Lens>> = (0..256).map(|_| Vec::new()).collect::<Vec<_>>();
for step in input.trim().split(',') {
let (lens, op) = parse_step(step);
let box_i = ascii_hash(lens.label);
let _box = boxes.get_mut(box_i).unwrap();
match op {
Operation::D => {
_box.retain(|l| l.label != lens.label);
}
Operation::E => {
if let Some(lens_i) = _box.iter().position(|l| l.label == lens.label) {
let _lens = _box.get_mut(lens_i).unwrap();
_lens.focal_len = lens.focal_len;
} else {
_box.push(lens);
}
}
}
}
calc_focussing_power(&boxes)
}
pub fn main(data_dir: &str) {
println!("Day 15: Lens Library");
let data = load(data_dir, 15, None);
// Puzzle 1.
let answer_1 = puzzle_1(&data);
println!(" Puzzle 1: {}", answer_1);
assert_eq!(answer_1, 504036);
// Puzzle 2.
let answer_2 = puzzle_2(&data);
println!(" Puzzle 2: {}", answer_2);
// assert_eq!(answer_2, Ok(30449))
}