summaryrefslogtreecommitdiffstats
path: root/day8/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'day8/src/main.rs')
-rw-r--r--day8/src/main.rs115
1 files changed, 115 insertions, 0 deletions
diff --git a/day8/src/main.rs b/day8/src/main.rs
new file mode 100644
index 0000000..4d18938
--- /dev/null
+++ b/day8/src/main.rs
@@ -0,0 +1,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);
+} \ No newline at end of file