-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-16.rs
119 lines (110 loc) · 3.23 KB
/
day-16.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::{str::FromStr, vec};
const INPUT: &str = include_str!("day-16.input");
struct Transmission {
bits: vec::IntoIter<bool>,
pos: usize,
version_sum: usize,
}
impl Transmission {
fn read_n(&mut self, n: usize) -> usize {
let mut value = 0;
self.pos += n;
for _ in 0..n {
value = (value << 1) + self.bits.next().unwrap() as usize;
}
value
}
fn packet(&mut self) -> usize {
self.version_sum += self.read_n(3);
match self.read_n(3) {
4 => self.literal(),
x => self.operator(x),
}
}
fn literal(&mut self) -> usize {
let mut value = 0;
while self.read_n(1) == 1 {
value = (value << 4) + self.read_n(4);
}
(value << 4) + self.read_n(4)
}
fn operator(&mut self, typeid: usize) -> usize {
let mut subpackets = Vec::new();
if self.read_n(1) == 0 {
let length = self.read_n(15);
let i = self.pos;
while self.pos - i < length {
subpackets.push(self.packet());
}
assert_eq!(self.pos - i, length);
} else {
let count = self.read_n(11);
for _ in 0..count {
subpackets.push(self.packet());
}
}
let mut it = subpackets.into_iter();
match typeid {
0 => it.sum(),
1 => it.product(),
2 => it.min().unwrap(),
3 => it.max().unwrap(),
5 => {
let a = it.next().unwrap();
let b = it.next().unwrap();
(a > b) as usize
}
6 => {
let a = it.next().unwrap();
let b = it.next().unwrap();
(a < b) as usize
}
7 => {
let a = it.next().unwrap();
let b = it.next().unwrap();
(a == b) as usize
}
_ => unreachable!(),
}
}
}
impl FromStr for Transmission {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self {
bits: s
.trim()
.chars()
.flat_map(|c| match c {
'0' => b"0000",
'1' => b"0001",
'2' => b"0010",
'3' => b"0011",
'4' => b"0100",
'5' => b"0101",
'6' => b"0110",
'7' => b"0111",
'8' => b"1000",
'9' => b"1001",
'A' => b"1010",
'B' => b"1011",
'C' => b"1100",
'D' => b"1101",
'E' => b"1110",
'F' => b"1111",
_ => panic!("unexpected `{}`", c),
})
.map(|&b| b != b'0')
.collect::<Vec<_>>()
.into_iter(),
pos: 0,
version_sum: 0,
})
}
}
fn main() {
let mut transmission = INPUT.parse::<Transmission>().unwrap();
let part_2 = transmission.packet();
println!("part 1: {}", transmission.version_sum);
println!("part 2: {}", part_2);
}