diff --git a/2022/rust/Cargo.toml b/2022/rust/Cargo.toml index e10a2b9..0416b00 100644 --- a/2022/rust/Cargo.toml +++ b/2022/rust/Cargo.toml @@ -38,4 +38,8 @@ path = "src/day5.rs" name = "day6" path = "src/day6.rs" +[[bin]] +name = "day7" +path = "src/day7.rs" + [dependencies] diff --git a/2022/rust/src/day7.rs b/2022/rust/src/day7.rs new file mode 100644 index 0000000..6244fc7 --- /dev/null +++ b/2022/rust/src/day7.rs @@ -0,0 +1,145 @@ +mod common; + +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +#[derive(Debug, Clone)] +struct DirTree { + files: HashMap, + subdirectories: HashMap>>, + parent: Option>>, +} + +impl DirTree { + pub fn new(parent: Option>>) -> Self { + Self { + files: HashMap::new(), + subdirectories: HashMap::new(), + parent, + } + } + + pub fn root() -> Self { + Self::new(None) + } + + pub fn size(&self) -> usize { + self.files.values().sum::() + + self + .subdirectories + .values() + .map(|v| v.borrow().size()) + .sum::() + } +} + +struct DirTreeIterator { + dir_tree: Rc>, +} + +impl IntoIterator for DirTree { + type Item = Rc>; + type IntoIter = std::iter::Chain< + std::iter::Once>>, + std::collections::hash_map::Values>>, + >; + + fn into_iter(&self) -> Self::IntoIter { + std::iter::once(Rc::new(RefCell::new(*self))) + .into_iter() + .chain(self.subdirectories.values().into_iter()) + } +} + +type Input = Rc>; +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); + if l == "$ cd /" { + current_dir = Rc::clone(&root); + } else if l == "$ ls" { + continue; + } else if l.starts_with("dir ") { + current_dir.borrow_mut().subdirectories.insert( + l[4..].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 cur = Rc::clone(¤t_dir); + current_dir = Rc::clone(&cur.borrow().subdirectories.get(&l[5..]).unwrap()); + } else { + let mut args = l.split(' '); + let size = args.next().unwrap().parse::().unwrap(); + current_dir + .borrow_mut() + .files + .insert(args.next().unwrap().to_string(), size); + } + } + return root; +} + +fn part1(input: &Input) -> Result { + 100 +} + +fn part2(input: &Input) -> Result { + 0 +} + +fn main() { + let input_text = common::day_input(7); + eprintln!("{}\n\nAbove is your input file.\n\n", input_text); + let input = processed_input(&input_text); + common::show_answers(&part1(&input), &part2(&input)) + // common::show_both_answers(&both_parts(&input)) +} + +// fn both_parts(input: &Input) -> (Result, Result) { +// (0, 0) +// } + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_INPUT: &str = "$ 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"; + + #[test] + fn test() { + let input = processed_input(TEST_INPUT); + assert_eq!(part1(&input), 95437); + assert_eq!(part2(&input), 0); + // assert_eq!(both_parts(&input), (0, 0)); + } +}