summaryrefslogtreecommitdiff
path: root/2018/src/day8.rs
diff options
context:
space:
mode:
Diffstat (limited to '2018/src/day8.rs')
-rw-r--r--2018/src/day8.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/2018/src/day8.rs b/2018/src/day8.rs
new file mode 100644
index 0000000..81f0d0b
--- /dev/null
+++ b/2018/src/day8.rs
@@ -0,0 +1,66 @@
+use std::io;
+use std::io::BufRead;
+
+pub fn main<T: BufRead>(reader: T) -> io::Result<(String, String)> {
+ #[derive(PartialEq, Eq)]
+ struct Entry {
+ nch: i32,
+ nmeta: i32,
+ }
+
+ let mut stk = vec![Entry {nch: 1, nmeta: 0}];
+ let mut total_meta = 0;
+ let mut vals: Vec<Vec<i32>> = vec![vec![]];
+ let mut current_val = 0;
+
+ for num in reader.lines().next().unwrap().unwrap().split(' ').map(|s| s.parse::<i32>().unwrap()) {
+ // Yay non-lexical lifetimes!
+ let l = stk.last_mut().unwrap();
+ if l.nmeta == -1 {
+ // println!("read nmeta {}", num);
+ l.nmeta = num;
+ continue;
+ }
+
+ if l.nmeta == 0 && l.nch == 0 {
+ loop {
+ // println!("pop");
+ stk.pop();
+
+ // println!(" node value {}", current_val);
+ vals.pop();
+ vals.last_mut().unwrap().push(current_val);
+ current_val = 0;
+
+ let l = stk.last().unwrap();
+ if l.nmeta != 0 || l.nch != 0 { break; }
+ }
+ }
+
+ let l = stk.last_mut().unwrap();
+ if l.nch == 0 {
+ // println!("+meta {}", num);
+ total_meta += num;
+
+ if vals.last().unwrap().len() == 0 {
+ // println!(" add value");
+ current_val += num;
+ } else if 1 <= num && num <= vals.last().unwrap().len() as i32 {
+ // println!(" add child value {}", vals.last().unwrap()[num as usize - 1]);
+ current_val += vals.last().unwrap()[num as usize - 1];
+ }
+
+ l.nmeta -= 1;
+ } else {
+ // println!("read nch {}", num);
+ l.nch -= 1;
+ stk.push(Entry {nch: num, nmeta: -1});
+ vals.push(vec![]);
+ }
+ }
+
+ let part1 = total_meta.to_string();
+ let part2 = current_val.to_string();
+
+ Ok((part1, part2))
+}