Files
aoc2016/src/bin/09.rs

79 lines
1.8 KiB
Rust

use itertools::Itertools;
fn decompress(input: &str, recursive: bool) -> usize {
let mut stack = input
.chars()
.filter(|x| !x.is_whitespace())
.rev()
.collect_vec();
let mut drained = vec![];
let mut count = 0;
while let Some(c) = stack.pop() {
if c == '(' {
let mut n = 0;
let sublen = loop {
let l = stack.pop().unwrap();
if l == 'x' {
break n;
}
n = n * 10 + l.to_digit(10).unwrap() as usize;
};
let mut n = 0;
let repeat = loop {
let l = stack.pop().unwrap();
if l == ')' {
break n;
}
n = n * 10 + l.to_digit(10).unwrap() as usize;
};
drained.clear();
for _ in 0..sublen {
drained.push(stack.pop().unwrap());
}
if recursive {
for _ in 0..repeat {
for d in drained.iter().copied().rev() {
stack.push(d);
}
}
} else {
count += drained.len() * repeat
}
} else {
count += 1
}
}
count
}
pub fn part_one(input: &str) -> Option<usize> {
Some(decompress(input, false))
}
pub fn part_two(input: &str) -> Option<usize> {
Some(decompress(input, true))
}
aoc::solution!(9);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let input = aoc::template::read_file("examples", 9);
assert_eq!(part_one(&input), Some(238));
}
#[test]
fn test_part_two() {
let input = aoc::template::read_file("examples", 9);
assert_eq!(part_two(&input), Some(445));
}
}