Rust challenge 69/100 - aoc 2022 day7 Dec 7, 2022 Table of content What is this 69th Challenge Challenge Solution What is this The rules of the game are explained in my original. 69th Challenge Challenge Solve today’s AOC challange.🎅🦀 Solution Here’s my solution, today was hard.. the Idea was easy, but implemnting it was hard. use std::collections::HashMap; const TOTAL_DISK_SPACE: u64 = 70000000; const MINIMUM_FREE_SPACE: u64 = 30000000; fn main() { let directories = include_str!("../input.txt").split_terminator("$") .filter(|x|x.len()>0) .map(Command::parse) .fold((vec![],HashMap::<String,Vec<Node>>::new()),|mut acc,curr| { match curr{ Command::CdUp() => {acc.0.pop();}, Command::Cd(_) => {acc.0.push(curr.name().unwrap().trim().to_string());}, Command::Ls(children) => { children.into_iter() .for_each(|mut node| { let child_path= [acc.0.join("/"),node.name].join("/"); let parent_path= acc.0.join("/"); node.name = child_path; acc.1.entry(parent_path).or_insert(vec![]).push(node); }); } }; acc }).1; let sum = directories.iter() .map(|(k,_v)| { size_of_node_in_tree(String::from(k), &directories) }).filter(|x| *x<100000).sum::<u64>(); println!("Sum of all files below size 10000: {}", sum); let used_disk_space = size_of_node_in_tree("/".to_string(), &directories); println!("Used disk space: {}", used_disk_space); let unused_disk_space = TOTAL_DISK_SPACE - used_disk_space; let required_additonal_space = MINIMUM_FREE_SPACE-unused_disk_space; println!("Unused disk space: {}", unused_disk_space); println!("Additional required space: {}",required_additonal_space); let mut sum:Vec<u64> = directories.iter() .map(|(k,_v)| { size_of_node_in_tree(String::from(k), &directories) }) .filter(|x| *x>required_additonal_space).collect(); sum.sort(); println!("File to delete: {}", sum.first().unwrap()); } #[derive(PartialEq,Debug)] struct Node { name: String, size: u64, } #[derive(PartialEq,Debug)] struct Response { value: String, } #[derive(PartialEq,Debug)] enum Command{ CdUp(), Cd(Node), Ls(Vec<Node>) } fn size_of_node_in_tree(file_name: String, directory_tree: &HashMap<String,Vec<Node>>) -> u64 { let mut size = 0; if let Some(nodes) = directory_tree.get(&file_name) { for node in nodes { if node.size == 0 { size += size_of_node_in_tree(node.name.to_string(), directory_tree); } else { size += node.size; } } } size } impl Command { fn parse(input: &str) -> Command { match input[0..3].to_owned().as_str() { " cd" => { if input.len()>5 && input[4..6].eq("..") { Command::CdUp() }else { Command::Cd(Node{name: input[4..].trim().to_string(), size: 0}) } }, " ls" => Command::Ls({ input.lines().skip(1).fold(vec![], |mut acc, line| { let mut line = line.split_whitespace(); let mut n = 0; if let Ok(number)=line.next().unwrap().parse::<u64>(){ n = number; } acc.push(Node{ name: line.next().unwrap().to_string(), size: n }); acc }) }), _ => panic!("Unknown command '{}'", input[0..3].to_owned().as_str()), } } fn name(&self) -> Option<String> { match self { Command::CdUp() => None, Command::Cd(node) => Some(node.name.to_string()), Command::Ls(_) => None, } } } #[cfg(test)] mod tests { use super::*; const LS_INPUT: &str = " ls dir a 14848514 b.txt 8504156 c.dat dir d"; #[test] fn it_works() { assert_eq!(Command::CdUp(), Command::parse(" cd ..")); assert_eq!(Command::Cd(Node{name: "/".to_string(), size: 0 }), Command::parse(" cd /")); assert_eq!(Command::Cd(Node{name: "abc".to_string(), size: 0 }), Command::parse(" cd abc")); assert_eq!(Command::Ls( vec![ Node { name: "a".to_string(), size: 0 }, Node { name: "b.txt".to_string(), size: 14848514 }, Node { name: "c.dat".to_string(), size: 8504156 }, Node { name: "d".to_string(), size: 0 }] ), Command::parse(LS_INPUT)); } #[test] fn test_size_of_node_in_tree() { let mut x= HashMap::new(); x.insert("x".to_string(),vec![ Node { name: "a".to_string(), size: 0 }, Node { name: "b.txt".to_string(), size: 14848514 }, Node { name: "c.dat".to_string(), size: 8504156 }, Node { name: "d".to_string(), size: 0 } ]); x.insert("a".to_string(), vec![ Node { name: "c.dat".to_string(), size: 8504156 } ]); x.insert("d".to_string(), vec![ Node { name: "c.dat".to_string(), size: 8504156 } ]); assert_eq!(size_of_node_in_tree("x".to_string(),&x), 8504156 + 14848514 + 8504156 + 8504156); assert_eq!(size_of_node_in_tree("a".to_string(),&x), 8504156); assert_eq!(size_of_node_in_tree("d".to_string(),&x), 8504156); } } Share on: