use std::env; use std::io::BufReader; use std::io::BufRead; use std::fs::File; use std::process; struct Node { n_children: usize, n_metadata: usize, children: Vec, metadata: Vec } impl Node { fn value(&self) -> u32 { if self.n_children == 0 { sum_metadata(&self) } else { let mut value: u32 = 0; for metadatum in &self.metadata { let i = (metadatum - 1) as usize; if i >= self.n_children { continue; } let child = &self.children[i]; value += child.value(); } value } } } fn build_tree(nums: &Vec, offset: usize, depth: u32) -> (Node, usize) { let mut i: usize = offset; for _k in 0..depth { print!(" "); } let n_children = nums[i] as usize; i += 1; let n_metadata = nums[i] as usize; i += 1; println!("n_children: {}, n_metadata: {}", n_children, n_metadata); let mut children: Vec = Vec::new(); let mut metadata: Vec = Vec::new(); for _j in 0..n_children { let (child, size) = build_tree(&nums, i, depth + 1); i += size; children.push(child); } for j in 0..n_metadata { let metadatum = nums[i]; i += 1; metadata.push(metadatum); } let node = Node { n_children, n_metadata, children, metadata }; (node, i - offset) } fn sum_metadata(node: &Node) -> u32 { let mut result: u32 = 0; for metadatum in &node.metadata { result += metadatum; } for child in &node.children { let sum = sum_metadata(child); result += sum; } result } fn main() { let args: Vec = env::args().collect(); if args.len() != 2 { println!("Wrong number of arguments. Provide a file name and worker count."); process::exit(1); } let filename = &args[1]; println!("Using file {} as input.", filename); let f = match File::open(filename) { Ok(file) => file, Err(e) => { println!("Failed to open file {}. {:?}", filename, e); process::exit(1); } }; let file = BufReader::new(&f); let lines: Vec = file.lines() .map(|line| line.expect("Could not parse line.")) .collect(); let is_more_than_one_line = lines.len() >= 1; assert!(is_more_than_one_line); let line_chars = &lines[0]; let strs: Vec<&str> = line_chars.split(" ").collect(); let mut nums: Vec = Vec::new(); for s in &strs { let num: u32 = s.parse().expect("Could not convert value to u32"); nums.push(num); } let (tree, _size) = build_tree(&nums, 0, 0); let result_1 = sum_metadata(&tree); println!("1. Result: {}", result_1); let result_2 = tree.value(); println!("2. Result: {}", result_2); }