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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
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<Node>,
metadata: Vec<u32>
}
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<u32>, 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<Node> = Vec::new();
let mut metadata: Vec<u32> = 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<String> = 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<String> = 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<u32> = 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);
}
|