From fa26f694d8cf98272763952a698301ee9935c19e Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Jun 2025 09:47:23 +0200 Subject: Added 2022, first few problems --- 2022/07/a.rs | 12 +++++ 2022/07/b.rs | 13 ++++++ 2022/07/common.rs | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 2022/07/a.rs create mode 100644 2022/07/b.rs create mode 100644 2022/07/common.rs (limited to '2022/07') diff --git a/2022/07/a.rs b/2022/07/a.rs new file mode 100644 index 0000000..a0d9a1a --- /dev/null +++ b/2022/07/a.rs @@ -0,0 +1,12 @@ +mod common; +use common::*; + +fn main() { + let fs = FileSystem::build_from_stdin(); + let sum: usize = fs.iter() + .filter(|f| matches!(f.kind, FileType::Directory(_))) + .map(|f| f.real_size(&fs)) + .filter(|s| *s <= 100000) + .sum(); + println!("{sum}"); +} diff --git a/2022/07/b.rs b/2022/07/b.rs new file mode 100644 index 0000000..92bedc7 --- /dev/null +++ b/2022/07/b.rs @@ -0,0 +1,13 @@ +mod common; +use common::*; + +fn main() { + let fs = FileSystem::build_from_stdin(); + let remaining = 70000000 - fs[0].real_size(&fs); + let ds: usize = fs.iter() + .filter(|f| matches!(f.kind, FileType::Directory(_))) + .map(|f| f.real_size(&fs)) + .filter(|s| *s + remaining >= 30000000) + .min().unwrap(); + println!("{ds}"); +} diff --git a/2022/07/common.rs b/2022/07/common.rs new file mode 100644 index 0000000..675bf29 --- /dev/null +++ b/2022/07/common.rs @@ -0,0 +1,130 @@ +use std::ops; + +pub enum FileType { + File(usize), + Directory(Vec) +} + +pub struct File { + pub kind: FileType, + name: String +} + +impl File { + pub fn real_size(&self, fs: &FileSystem) -> usize { + match &self.kind { + FileType::File(s) => *s, + FileType::Directory(c) => + c.iter().map(|x: &usize| fs[*x].real_size(&fs)).sum() + } + } +} + +pub struct FileSystem { + files: Vec +} + +impl FileSystem { + fn new() -> Self { + Self { + files: vec![File { + kind: FileType::Directory(Vec::::new()), + name: String::from("/") + }] + } + } + + pub fn build_from_stdin() -> Self { + let mut fs = FileSystem::new(); + let mut path = Path::new(); + let mut line = String::new(); + while std::io::stdin().read_line(&mut line).unwrap() > 0 { + if &line[..5] == "$ cd " { + exec_cd(&line[5..], &mut path, &fs); + } else if &line[..3] == "dir" { + fs.add_dir(&line[4..line.len()-1], path.last()); + } else if line.as_bytes()[0] != '$' as u8 { + let i = line.find(' ').unwrap(); + let size = line[0..i].parse::().unwrap(); + fs.add_file(&line[i+1..line.len()-1], size, path.last()); + } + line.clear(); + } + fs + } + + fn make_parent(&mut self, id: usize, parent: usize) { + let p = &mut self.files[parent]; + if let FileType::Directory(v) = &mut p.kind { + v.push(id); + } else { + panic!("Parent is not a directory"); + } + } + + fn add_dir(&mut self, name: &str, parent: usize) { + let id = self.files.len(); + self.files.push( + File { + kind: FileType::Directory(Vec::::new()), + name: String::from(name) + } + ); + self.make_parent(id, parent); + } + + fn add_file(&mut self, name: &str, size: usize, parent: usize) { + let id = self.files.len(); + self.files.push( + File { + kind: FileType::File(size), + name: String::from(name) + } + ); + self.make_parent(id, parent); + } + + pub fn iter(&self) -> impl Iterator{ + self.files.iter() + } +} + +impl ops::Index for FileSystem { + type Output = File; + fn index(&self, i: usize) -> &File { + &self.files[i] + } +} + +struct Path { + stack: Vec +} + +impl Path { + fn new() -> Self { Self { stack: vec![0] } } // 0 is the id of "/" + fn last(&self) -> usize { *self.stack.last().unwrap() } + fn clear(&mut self) { self.stack.drain(1..); } + fn pop(&mut self) { self.stack.pop(); } + fn push(&mut self, dir_id: usize) { self.stack.push(dir_id); } +} + +fn exec_cd(line: &str, path: &mut Path, fs: &FileSystem) { + if line.as_bytes()[0] == '/' as u8 { + path.clear(); + } else if &line[..2] == ".." { + path.pop(); + } else { + let current_dir = &fs[path.last()]; + if let FileType::Directory(children) = ¤t_dir.kind { + for c in children { + if fs[*c].name == &line[..line.len()-1] { + path.push(*c); + return; + } + } + } else { + panic!("Non-directory in path"); + } + panic!("Directory not found in current path"); + } +} -- cgit v1.3