use crate::read; use indextree::Arena; #[derive(Debug)] struct Directory { pub size: usize, pub name: String } pub fn run() { let arena = &mut Arena::new(); let mut current_directory = arena.new_node(Directory { size: 0, name: "/".into(), }); let root = current_directory; for line in read("07").lines().skip(1) { if line.starts_with("$ cd") { current_directory = match line.split_once("cd ").unwrap().1 { dirname if ".." == dirname => arena.get(current_directory).unwrap().parent().unwrap(), dirname => current_directory .children(arena) .find(|c|arena.get(*c).unwrap().get().name == dirname) .unwrap_or_else(||{ let nc = arena.new_node(Directory { size: 0, name: dirname.into(), }); current_directory.append(nc, arena); nc }) }; } else if line.chars().next().unwrap().is_numeric() { let filesize: usize = line.split_once(" ").unwrap().0.parse().unwrap(); arena.get_mut(current_directory).unwrap().get_mut().size += filesize; } } let total = root.descendants(arena).map(|desc|{ desc .descendants(arena) .map(|d|arena.get(d).unwrap().get().size) .sum::() }).collect::>(); #[cfg(feature = "part1")] { println!("Day 7, Part 01: {}", total.clone().iter() .filter(|s| *s <= &100000) .sum::()); } #[cfg(feature = "part2")] { let total_used = root.descendants(arena) .map(|d|arena.get(d).unwrap().get().size) .sum::(); let free_needed = total_used - 40000000; println!("Day 7, Part 02: {}", total.iter() .filter(|s|*s >= &free_needed) .min() .unwrap()); } }