diff --git a/src/main.rs b/src/main.rs index 869954b..fcb0941 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,55 +1,5 @@ use std::ops::Deref; -#[derive(Debug, Clone)] -enum Item { - Directory { name: String, items: Vec }, - File { size: u64, name: String }, -} - -impl Item { - // recursively gets the directory size - fn get_size(&self) -> u64 { - match self { - Item::File { size, .. } => *size, - Item::Directory { items, .. } => { - let mut total_size = 0; - for item in items { - total_size += item.get_size(); - } - total_size - } - } - } - - fn add_item(&mut self, item: Item) { - match self { - Item::Directory { items, .. } => { - items.push(item); - } - _ => panic!("Cannot add item to file"), - } - } -} - -// part one -// get the sum of the total size of every directory that has a size < 100000 -fn sum_directories_part_one(item: &mut Item) -> u64 { - let mut total_size_current_directory = 0; - let size = item.get_size(); - - if let Item::Directory { items, .. } = item { - if size < 100000 { - total_size_current_directory += size - } - - for item in items { - total_size_current_directory += sum_directories_part_one(item); - } - } - - total_size_current_directory -} - fn read_input() -> String { std::fs::read_to_string("input.txt").expect("Unable to read file") } @@ -158,6 +108,79 @@ fn process_input(input: &str) -> Item { root } +#[derive(Debug, Clone)] +enum Item { + Directory { name: String, items: Vec }, + File { size: u64, name: String }, +} + +impl Item { + // recursively gets the directory size + fn get_size(&self) -> u64 { + match self { + Item::File { size, .. } => *size, + Item::Directory { items, .. } => { + let mut total_size = 0; + for item in items { + total_size += item.get_size(); + } + total_size + } + } + } + + fn add_item(&mut self, item: Item) { + match self { + Item::Directory { items, .. } => { + items.push(item); + } + _ => panic!("Cannot add item to file"), + } + } +} + +// part one +// get the sum of the total size of every directory that has a size < 100000 +fn sum_directories_part_one(item: &mut Item) -> u64 { + let mut total_size_current_directory = 0; + let size = item.get_size(); + + if let Item::Directory { items, .. } = item { + if size < 100000 { + total_size_current_directory += size + } + + for item in items { + total_size_current_directory += sum_directories_part_one(item); + } + } + + total_size_current_directory +} + +// part two +// get the size of the smallest directory that would free up enough space. +fn get_smallest_dir_with_min_size(item: &mut Item, min_size_to_free: u64) -> u64 { + // make sure not to get a file size as the most optimal + let mut curr_smallest_size = match item { + Item::Directory { name: _, items: _ } => item.get_size(), + _ => std::u64::MAX, + }; + + println!("current directory size: {}", curr_smallest_size); + + if let Item::Directory { items, .. } = item { + for item in items { + let sub_dir_size = get_smallest_dir_with_min_size(item, min_size_to_free); + if sub_dir_size < curr_smallest_size && sub_dir_size >= min_size_to_free { + curr_smallest_size = sub_dir_size; + } + } + } + + curr_smallest_size +} + fn main() { println!("hello world"); @@ -165,7 +188,17 @@ fn main() { let mut root = process_input(&input); let total_size = sum_directories_part_one(&mut root); - println!("total size: {}", total_size); + println!("part 1: total size: {}", total_size); + + let size_of_root = root.get_size(); + println!("part 2: size of root: {}", size_of_root); + let total_disk = 70000000; + let needed_space = 30000000; + let space_to_free = needed_space - (total_disk - size_of_root); + println!("part 2: space to free: {}", space_to_free); + + let smallest_dir_size = get_smallest_dir_with_min_size(&mut root, space_to_free); + println!("part 2: smallest dir size: {}", smallest_dir_size); } #[cfg(test)] @@ -200,4 +233,36 @@ $ ls let total_size = super::sum_directories_part_one(&mut root); assert_eq!(total_size, 95437); } + + #[test] + fn part_two_example() { + let input = r#"$ cd / +$ ls +dir a +14848514 b.txt +8504156 c.dat +dir d +$ cd a +$ ls +dir e +29116 f +2557 g +62596 h.lst +$ cd e +$ ls +584 i +$ cd .. +$ cd .. +$ cd d +$ ls +4060174 j +8033020 d.log +5626152 d.ext +7214296 k +"#; + let mut root = super::process_input(input); + let most_optimal_dir_to_delete_size = + super::get_smallest_dir_with_min_size(&mut root, 8381165); + assert_eq!(most_optimal_dir_to_delete_size, 24933642); + } }