From 259a0d7d2fdc675f9d19bb04776cf2bbf3c425c9 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 8 Dec 2022 01:46:06 +0800 Subject: [PATCH] =?UTF-8?q?day=207=20Was=20feeling=20lazy=20today=20and=20?= =?UTF-8?q?did=20it=20in=20python=20=F0=9F=92=80=20Have=20to=20learn=20how?= =?UTF-8?q?=20the=20various=20pointer=20types=20work=20for=20rust,=20this?= =?UTF-8?q?=20was=20the=20main=20blocker=20preventing=20me=20from=20creati?= =?UTF-8?q?ng=20a=20recursive=20data=20structure=20to=20store=20the=20tree?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- day_7/python/main.py | 86 ++++++++++++++++++++++++++++++++++++++++++++ day_7/src/main.rs | 85 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 day_7/python/main.py diff --git a/day_7/python/main.py b/day_7/python/main.py new file mode 100644 index 0000000..c324710 --- /dev/null +++ b/day_7/python/main.py @@ -0,0 +1,86 @@ + +from typing import Callable + + +class Directory: + def __init__(self: "Directory", parent: "Directory|None", name: str) -> None: + self.name=name + self.parent=parent + self.subdirectories: dict[str,Directory] = dict() + self.files: dict[str,int] = dict() + self.size=0 + + def update_size(self: "Directory") -> int: + for dir in self.subdirectories.values(): + self.size += dir.update_size() + + self.size += sum(self.files.values()) + + return self.size + + def match_expr(self: "Directory", expr:Callable[["Directory"],bool]) -> list: + matched: list[Directory] = [] + if expr(self): + matched.append(self) + + for dir in self.subdirectories.values(): + matched.extend(dir.match_expr(expr)) + + return matched + + def __lt__(self: "Directory", other: "Directory")->bool: + return self.size < other.size + + def __str__(self) -> str: + return self.to_str(" ") + + def to_str(self:"Directory", padding: str)->str: + newline='\n' + next_depth = " " + padding + return f"""{padding}{self.name} ({self.size}) +{newline.join({f"{next_depth}{k} - {v}" for k,v in self.files.items()})} +{newline.join([f"{x.to_str(next_depth)}" for x in self.subdirectories.values()])} +""" + +P1_MAX_SIZE = 100000 +P2_DISK_SIZE = 70000000 +P2_TARGET_FREE_SIZE = 30000000 + +def main(): + directory = treeify() + directory.update_size() + # print(directory) + print(f"PART 1 {sum([x.size for x in directory.match_expr(lambda d: d.size<=P1_MAX_SIZE)])}") + + free_size = P2_DISK_SIZE - directory.size + required_size = P2_TARGET_FREE_SIZE - free_size + deletion_candidates=directory.match_expr(lambda d: d.size>=required_size) + deletion_candidates.sort() + # print([f"{x.name} {x.size}" for x in deletion_candidates]) + print(f"PART 2 {deletion_candidates[0].size}") + + +def treeify() -> Directory: + directory:Directory = Directory(None,"root") + pwd:Directory=directory + with open("src/input","r") as f: + for line in f: + tokens = line.strip().split(' ') + if tokens[0] == '$': + if tokens[1] == "cd": + if tokens[2] == "..": + pwd = pwd.parent + elif tokens[2] not in pwd.subdirectories: + new_dir = Directory(pwd, tokens[2]) + pwd.subdirectories.update({tokens[2]: new_dir}) + pwd = new_dir + else: + pwd = pwd.subdirectories.get(tokens[2]) + elif tokens[1] == "ls": + pass + elif tokens[0].isdecimal(): + pwd.files.update({tokens[1]: int(tokens[0])}) + return directory + +if __name__=="__main__": + main() \ No newline at end of file diff --git a/day_7/src/main.rs b/day_7/src/main.rs index e7a11a9..f867e37 100644 --- a/day_7/src/main.rs +++ b/day_7/src/main.rs @@ -1,3 +1,84 @@ -fn main() { - println!("Hello, world!"); +use std::{cell::RefCell, fs::read_to_string, ops::Deref, rc::Rc}; + +#[derive(Eq, PartialEq)] +enum STATE { + COMMAND, + LISTING, +} + +// fn process_dir<'a>(cd_path: &'a str, stack: &mut Vec<&'a str>) { +// if cd_path.eq("..") { +// stack.pop(); +// // WE CAN ASSUME THE ONLY ABSOLUTE PATH USED IS THE / +// } else if cd_path.eq("/") { +// stack.truncate(0); +// } else { +// stack.push(cd_path); +// } +// } + +struct File { + name: String, + size: u32, +} +struct Directory<'a> { + name: &'a str, + parent: Option>>>, + subdirs: Vec>>>, + files: Vec, +} + +impl<'a> Directory<'a> { + fn new(name: &'a str, parent: Option>>>) -> Directory<'a> { + Directory { + name, + parent, + subdirs: Vec::new(), + files: Vec::new(), + } + } + + fn cd_mkdir(&'a mut self, name: &'a str) -> &Box { + for subdir in &self.subdirs { + let t = subdir.deref().as_ptr().name; + if subdir.deref().name.eq(name) { + return subdir; + } + } + let dir = Box::from(Directory::new(name, None)); + self.subdirs.push(dir); + return &dir; + } +} + +const PATH: &str = "src/input"; +fn main() { + let binding = read_to_string(PATH).expect("Error reading file"); + assert!(binding.is_ascii()); + let history = binding.split("\n").into_iter(); + + let root_directory = Box::from(Directory::new("root", None)); + let mut current_directory = root_directory; + + let mut state = STATE::COMMAND; + + for line in history { + let mut tokens = line.split_ascii_whitespace(); + if tokens.next().unwrap().eq("$") { + let cmd_token = tokens.next().unwrap(); + if cmd_token.eq("dir") { + let directory = tokens.next().unwrap(); + let next_state: &Box; + if directory.eq("..") { + // next_state = ¤t_directory.parent.unwrap() + } else { + // next_state = &; + } + current_directory = *current_directory.cd_mkdir(directory); + } else if cmd_token.eq("ls") { + } else { + panic!("INVALID STATE"); + } + } + } }