diff options
Diffstat (limited to '2018/src')
| -rw-r--r-- | 2018/src/day8.rs | 66 | ||||
| -rw-r--r-- | 2018/src/main.rs | 4 | 
2 files changed, 69 insertions, 1 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)) +} diff --git a/2018/src/main.rs b/2018/src/main.rs index fccb319..8d2f368 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -16,8 +16,9 @@ mod day4;  mod day5;  mod day6;  mod day7; +mod day8; -static NUM_DAYS: i32 = 7; +static NUM_DAYS: i32 = 8;  fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<(String, String)> {      match day { @@ -28,6 +29,7 @@ fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<(String, String)> {          5 => day5::main(reader),          6 => day6::main(reader),          7 => day7::main(reader), +        8 => day8::main(reader),          _ => Err(Error::new(ErrorKind::Other, "Invalid day"))      }  } | 
