summaryrefslogtreecommitdiff
path: root/2018/src/bin/day_8.rs
blob: 59813b0da9186a4b64b23abf70175aebe6ba4440 (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
extern crate advent_of_code_2018;
use advent_of_code_2018::*;

use std::error::Error;
use std::path::PathBuf;

use std::slice::Iter;

// cargo watch -cs "cargo run --release --bin day_8"

fn main() -> Result<(), Box<Error>> {
    let input: Vec<u32> = read_file(&PathBuf::from("inputs/8.txt"))
        .map(|lines| lines[0]
             .split_whitespace()
             .map(|s| s.parse().unwrap())
             .collect()
        )?;

    //println!("Input: {:?}", input);

    let metadata_sum = sum_metadata(&mut input.iter());
    debug!(metadata_sum);

    let value = node_value(&mut input.iter());
    debug!(value);

    Ok(())
}

fn sum_metadata(iter: &mut Iter<'_, u32>) -> u32 {
    let num_children = iter.next().unwrap().clone();
    let num_metadata = iter.next().unwrap().clone();

    let children_sum: u32 = (0..num_children)
        .map(|_| sum_metadata(iter))
        .sum();

    let metadata_sum: u32 = (0..num_metadata)
        .map(|_| iter.next().unwrap())
        .sum();

    children_sum + metadata_sum
}


fn node_value(iter: &mut Iter<'_, u32>) -> u32 {
    let num_children = iter.next().unwrap().clone();
    let num_metadata = iter.next().unwrap().clone();

    let node_values: Vec<u32> = (0..num_children)
        .map(|_| node_value(iter))
        .collect();

    let metadata: Vec<u32> = (0..num_metadata)
        .map(|_| iter.next().unwrap().clone())
        .collect();

    if num_children == 0 {
        metadata.iter().sum()
    } else {
        metadata.iter()
            .filter(|m| **m > 0 && **m-1 < num_children)
            .map(|m| node_values[*m as usize - 1])
            .sum()
    }
}