This commit is contained in:
Daniel Flanagan 2022-12-07 21:15:09 -06:00
parent 7568b54f38
commit de796bdb0a
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4

View file

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