diff --git a/2022/rust/src/day7.rs b/2022/rust/src/day7.rs index 6958e53..fb99fff 100644 --- a/2022/rust/src/day7.rs +++ b/2022/rust/src/day7.rs @@ -2,6 +2,7 @@ mod common; use std::cell::RefCell; use std::collections::HashMap; +use std::collections::HashSet; use std::rc::Rc; #[derive(Debug, Clone)] @@ -31,23 +32,26 @@ type Result = usize; fn processed_input(input: &str) -> Input { let root = Rc::new(RefCell::new(DirTree::root())); let mut current_dir = Rc::clone(&root); + for l in input.lines() { - println!("{}", l); + println!("line: {}", l); if l == "$ cd /" { current_dir = Rc::clone(&root); } else if l == "$ ls" { continue; } else if l.starts_with("dir ") { + let d = &l[4..]; current_dir.borrow_mut().subdirectories.insert( - l[4..].to_string(), + d.to_string(), Rc::new(RefCell::new(DirTree::new(Some(Rc::clone(¤t_dir))))), ); } else if l.starts_with("$ cd ..") { let cur = Rc::clone(¤t_dir); current_dir = Rc::clone(&cur.borrow().parent.as_ref().unwrap()); } else if l.starts_with("$ cd ") { + let d = &l[5..]; let cur = Rc::clone(¤t_dir); - current_dir = Rc::clone(&cur.borrow().subdirectories.get(&l[5..]).unwrap()); + current_dir = Rc::clone(&cur.borrow().subdirectories.get(d).unwrap()); } else { let mut args = l.split(' '); let size = args.next().unwrap().parse::().unwrap(); @@ -62,26 +66,38 @@ fn processed_input(input: &str) -> Input { const PART1_LIMIT: usize = 100_000; -fn dfs1(input: Input, acc: usize) -> usize { +fn dfs1(input: Input, path: String) -> usize { let dt = input.borrow(); - let subdir_sizes = dt.subdirectories.values().map(|sdt| dfs1(sdt.clone(), acc)); - let file_sizes = dt.files.values().map(|r| r.to_owned()); + let files_size = dt.files.values().map(|r| r.to_owned()).sum::(); + let subdir_sizes: Vec = dt + .subdirectories + .iter() + .map(|(p, sdt)| dfs1(sdt.clone(), format!("{}/{}", path, p))) + .collect(); + let subdirs_size = subdir_sizes.iter().sum::(); + let this_dir_size = subdirs_size + files_size; - let this_dir_size = subdir_sizes.clone().chain(file_sizes).sum::(); + let counted = subdir_sizes.iter().filter(|s| **s < PART1_LIMIT).sum(); - let new_acc = acc + subdir_sizes.filter(|sd| *sd < PART1_LIMIT).sum::(); + println!( + "path: {}, files: {:?}, files_size: {}, subdirs_size: {}, counted: {}", + path, dt.files, files_size, subdirs_size, counted + ); + let mut r = counted; if this_dir_size < PART1_LIMIT { - return new_acc + this_dir_size; - } else { - return new_acc; + r = counted + this_dir_size; } + println!( + "return {}, {}", + counted + this_dir_size, + "hy" // std::backtrace::Backtrace::capture() + ); + return r; } fn part1(input: &Input) -> Result { - let r = dfs1(input.clone(), 0); - println!("{} /", r); - r + dfs1(input.clone(), "".to_string()) } fn part2(input: &Input) -> Result { @@ -135,4 +151,48 @@ $ ls assert_eq!(part2(&input), 0); // assert_eq!(both_parts(&input), (0, 0)); } + + const TEST_INPUT2: &str = "$ cd / +$ ls +dir a +100 x.txt +$ cd a +$ ls +dir b +100 y.txt +$ cd b +$ ls +100 z.txt"; + const TEST_INPUT3: &str = "$ cd / +$ ls +dir a +100 x.txt +$ cd a +$ ls +dir b +100 y.txt +$ cd b +$ ls +dir c +100 z.txt +$ cd c +$ ls +100 zz.txt"; + // $ cd a + // $ ls + // dir a + // 100 c.txt + // $ cd a + // $ ls + // 100 d.txt + // "; + + #[test] + fn test2() { + let input = processed_input(TEST_INPUT2); + assert_eq!(part1(&input), 600); + let input3 = processed_input(TEST_INPUT2); + assert_eq!(part1(&input), 1000); + // assert_eq!(both_parts(&input), (0, 0)); + } }