From 6fc5cf34a4e0f927d6b694f6f516d61ca74251e8 Mon Sep 17 00:00:00 2001 From: Dory Date: Sun, 10 Mar 2024 18:37:30 -0700 Subject: [PATCH] d7p2 --- day7/src/main.rs | 11 +++--- day7/src/main1.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 day7/src/main1.rs diff --git a/day7/src/main.rs b/day7/src/main.rs index d851602..2dc7ee1 100644 --- a/day7/src/main.rs +++ b/day7/src/main.rs @@ -3,6 +3,8 @@ use std::fs::File; use std::io::{self, BufRead}; use std::collections::HashMap; +const MAX_SIZE: usize = 70_000_000 - 30_000_000; + fn main() { let file = File::open(&env::args().nth(1).unwrap()).unwrap(); let mut lines = io::BufReader::new(file).lines(); @@ -37,11 +39,12 @@ fn main() { } } - let sum: usize = (0..tree.inodes.len()) + let total_size = tree.size_of(0); + let answer: usize = (0..tree.inodes.len()) .map(|inode| tree.size_of(inode)) - .filter(|size| *size <= 100000) - .sum(); - println!("{:?}", sum); + .filter(|size| total_size - *size <= MAX_SIZE) + .min().unwrap(); + println!("{:?}", answer); } #[derive(Debug)] diff --git a/day7/src/main1.rs b/day7/src/main1.rs new file mode 100644 index 0000000..d851602 --- /dev/null +++ b/day7/src/main1.rs @@ -0,0 +1,91 @@ +use std::env; +use std::fs::File; +use std::io::{self, BufRead}; +use std::collections::HashMap; + +fn main() { + let file = File::open(&env::args().nth(1).unwrap()).unwrap(); + let mut lines = io::BufReader::new(file).lines(); + let mut tree = DirTree::new(); + let mut cwd = 0; + + loop { + let tokens: Vec<_> = if let Some(Ok(l)) = lines.next() { + l.split_whitespace().map(String::from).collect() + } else { break; }; + + if tokens[0] == "$" { + if tokens[1] == "cd" { + if tokens[2] == ".." { + cwd = tree.inodes[cwd].parent.unwrap(); + } else if tokens[2] == "/" { + cwd = 0; + } else { + let subdir = tree.inodes[cwd].subdirs[&tokens[2]]; + cwd = subdir; + } + } else if tokens[1] == "ls" { + continue; + } + } else if tokens[0] == "dir" { + tree.add_subdir_to(cwd, tokens[1].clone()); + } else { + tree.add_file_to( + cwd, + tokens[1].clone(), + tokens[0].parse::().unwrap()); + } + } + + let sum: usize = (0..tree.inodes.len()) + .map(|inode| tree.size_of(inode)) + .filter(|size| *size <= 100000) + .sum(); + println!("{:?}", sum); +} + +#[derive(Debug)] +struct Dir { + pub files: HashMap, // file name and size + pub subdirs: HashMap, // dir name and index into arena + pub parent: Option, // index into arena +} + +#[derive(Debug)] +struct DirTree { + inodes: Vec, +} + +impl DirTree { + fn new() -> Self { + let newdir = Dir { + files: HashMap::new(), + subdirs: HashMap::new(), + parent: None, + }; + DirTree { inodes: vec![newdir] } + } + + fn add_subdir_to(&mut self, idx: usize, name: String) { + let newidx = self.inodes.len(); + let newdir = Dir { + files: HashMap::new(), + subdirs: HashMap::new(), + parent: Some(idx), + }; + self.inodes.push(newdir); + self.inodes[idx].subdirs.insert(name, newidx); + } + + fn add_file_to(&mut self, idx: usize, name: String, size: usize) { + self.inodes[idx].files.insert(name, size); + } + + fn size_of(&self, inode: usize) -> usize { + let size_files: usize = self.inodes[inode].files.values().sum(); + let size_dirs: usize = self.inodes[inode].subdirs.values() + .fold(0, |acc, subdir_inode| acc + self.size_of(*subdir_inode)); + size_files + size_dirs + } +} +