<commit_before><commit_msg>2018: Day 8, Exercise 2.<commit_after>typealias Data = Int

typealias Metadata = Int

struct Node {
    let metadata: [Metadata]
    let children: [Node]

    var value: Metadata {
        if children.isEmpty {
            return metadata.reduce(0, +)
        }
        return metadata.map({ index in children.count >= index ? children[index - 1].value : 0 }).reduce(0, +)
    }
}

func main() {
    let tokens = readLine()!.split(separator: " ").map({ Data($0)! })
    let (tree, _) = parseNode(data: tokens.dropFirst(0))
    print(tree.value)
}

func parseNode(data: ArraySlice<Data>) -> (Node, ArraySlice<Data>) {
    let childrenCount = data[data.startIndex]
    let metadataCount = data[data.index(after: data.startIndex)]
    var children: [Node] = []
    var remaining = data.dropFirst(2)
    for _ in 0 ..< childrenCount {
        let child: Node
        (child, remaining) = parseNode(data: remaining)
        children.append(child)
    }
    let metadata = Array(remaining.prefix(metadataCount))
    remaining = remaining.dropFirst(metadataCount)
    return (Node(metadata: metadata, children: children), remaining)
}
{'fraction_non_alphanumeric': 0.134315424610052, 'fraction_numerical': 0.012131715771230503, 'mean_word_length': 3.2, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4500102', 'n_tokens_mistral': 359, 'n_tokens_neox': 346, 'n_words': 88}