Skip to content

Commit 5ae5a93

Browse files
author
mflinn-broad
committed
day 16 part 1
1 parent 675f3d4 commit 5ae5a93

File tree

1 file changed

+72
-8
lines changed

1 file changed

+72
-8
lines changed

src/days/day16.rs

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub fn run() {
44
let raw_input = util::read_input("inputs/day16.txt").unwrap();
55
let input = process(&raw_input);
66

7-
println!("{:?}", input);
7+
println!("Part 1: {:?}", part_1(&input));
88
}
99

1010
fn process(input: &str) -> Vec<u8> {
@@ -50,16 +50,71 @@ fn parse_literal(mut bytes: &[u8]) -> &[u8] {
5050
continues
5151
})
5252
.count();
53-
53+
5454
bytes
5555
}
5656

57-
fn parse_packet(bytes: &[u8]) -> (&[u8], u8) {
57+
fn parse_operator(mut bytes: &[u8]) -> (&[u8], u64) {
58+
let length_type = bytes[0];
59+
bytes = &bytes[1..];
60+
61+
match length_type {
62+
0 => {
63+
let l = bytes
64+
.iter()
65+
.take(15)
66+
.fold(0, |l, &bit| ((l as usize) << 1) ^ bit as usize);
67+
bytes = &bytes[15..];
68+
let rest = &bytes[l..];
69+
let mut sub_packets = &bytes[0..l];
70+
let mut sub_packet_version_count = 0;
71+
while !sub_packets.is_empty() {
72+
let (new_sub_packets, vers) = parse_packet(sub_packets);
73+
sub_packet_version_count += vers;
74+
sub_packets = new_sub_packets;
75+
}
76+
(rest, sub_packet_version_count)
77+
}
78+
1 => {
79+
let desired_sub_packet_count = bytes
80+
.iter()
81+
.take(11)
82+
.fold(0, |l, &bit| ((l as u32) << 1) ^ bit as u32);
83+
bytes = &bytes[11..];
84+
let sub_packet_versions = (0..desired_sub_packet_count)
85+
.map(|_| {
86+
let (rem, vers) = parse_packet(bytes);
87+
bytes = rem;
88+
vers
89+
})
90+
.sum::<u64>();
91+
92+
(bytes, sub_packet_versions)
93+
}
94+
_ => panic!("unreachable"),
95+
}
96+
}
97+
98+
fn parse_packet(bytes: &[u8]) -> (&[u8], u64) {
5899
let (rest, curr_vers, packet_type) = parse_header(bytes);
59100
match packet_type {
60-
Type::Literal => (parse_literal(rest), curr_vers),
61-
Type::Operator => todo!()
101+
Type::Literal => (parse_literal(rest), curr_vers as u64),
102+
Type::Operator => {
103+
let (rest, sub_packet_versions) = parse_operator(rest);
104+
(rest, curr_vers as u64 + sub_packet_versions)
105+
}
106+
}
107+
}
108+
109+
fn part_1(mut input: &[u8]) -> u64 {
110+
let mut vers_sum = 0;
111+
while input.len() > 6 {
112+
let res = parse_packet(input);
113+
input = res.0;
114+
vers_sum += res.1;
62115
}
116+
117+
vers_sum
63118
}
64119

65120
#[derive(Debug, PartialEq, Eq)]
@@ -109,10 +164,19 @@ mod tests {
109164

110165
#[test]
111166
fn test_parse_literal() {
112-
let rem = parse_literal(&[1,0,1,0,1,1,0,0,1,0,0,0,1,0,1]);
167+
let rem = parse_literal(&[1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1]);
113168
assert!(rem.is_empty());
114169

115-
let rem = parse_literal(&[1,0,1,0,1,1,0,0,1,0,0,0,1,0,1,1,0,1]);
116-
assert_eq!(rem, &[1,0,1]);
170+
let rem = parse_literal(&[1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1]);
171+
assert_eq!(rem, &[1, 0, 1]);
172+
}
173+
174+
#[test]
175+
fn test_part_1() {
176+
let input = "8A004A801A8002F478";
177+
let input = process(input);
178+
let res = part_1(&input);
179+
assert_eq!(res, 16);
180+
117181
}
118182
}

0 commit comments

Comments
 (0)