-
Notifications
You must be signed in to change notification settings - Fork 9
/
day09.rs
53 lines (42 loc) · 1.31 KB
/
day09.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
//! # Explosives in Cyberspace
//!
//! The only difference between part one and two is that we recursively decompress inner sequences.
use crate::util::parse::*;
pub fn parse(input: &str) -> &[u8] {
input.trim().as_bytes()
}
pub fn part1(input: &[u8]) -> usize {
decompress(input, false)
}
pub fn part2(input: &[u8]) -> usize {
decompress(input, true)
}
fn decompress(mut slice: &[u8], recurse: bool) -> usize {
let mut length = 0;
while !slice.is_empty() {
if slice[0] == b'(' {
let (next, amount) = number(slice);
let (next, repeat) = number(next);
let start = 1;
let end = start + amount;
let result = if recurse { decompress(&next[start..end], true) } else { amount };
slice = &next[end..];
length += result * repeat;
} else {
slice = &slice[1..];
length += 1;
}
}
length
}
fn number(slice: &[u8]) -> (&[u8], usize) {
// Parse number digit by digit, skipping over the delimeter at the start but leaving the
// delimeter at the end.
let mut index = 2;
let mut acc = slice[1].to_decimal() as usize;
while slice[index].is_ascii_digit() {
acc = 10 * acc + slice[index].to_decimal() as usize;
index += 1;
}
(&slice[index..], acc)
}