mirror of
https://github.com/peter-tanner/advent-of-code-2022.git
synced 2024-11-30 14:20:22 +08:00
day 7 Was feeling lazy today and did it in python 💀
Have to learn how the various pointer types work for rust, this was the main blocker preventing me from creating a recursive data structure to store the tree.
This commit is contained in:
parent
f54f65ca69
commit
259a0d7d2f
86
day_7/python/main.py
Normal file
86
day_7/python/main.py
Normal file
|
@ -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()
|
|
@ -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<Rc<RefCell<Directory<'a>>>>,
|
||||
subdirs: Vec<Rc<RefCell<Directory<'a>>>>,
|
||||
files: Vec<File>,
|
||||
}
|
||||
|
||||
impl<'a> Directory<'a> {
|
||||
fn new(name: &'a str, parent: Option<Rc<RefCell<Directory<'a>>>>) -> Directory<'a> {
|
||||
Directory {
|
||||
name,
|
||||
parent,
|
||||
subdirs: Vec::new(),
|
||||
files: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cd_mkdir(&'a mut self, name: &'a str) -> &Box<Directory> {
|
||||
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<Directory>;
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user