aboutsummaryrefslogtreecommitdiff
path: root/2022/07
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-06-26 09:47:23 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-06-26 23:37:23 +0200
commitfa26f694d8cf98272763952a698301ee9935c19e (patch)
tree5af7a788fb8e9fa12b2b2fbea64250ed496a23c0 /2022/07
parentf0159b7d36e2c81182f2d047a34bf883394894db (diff)
downloadaoc-fa26f694d8cf98272763952a698301ee9935c19e.tar.gz
aoc-fa26f694d8cf98272763952a698301ee9935c19e.zip
Added 2022, first few problems
Diffstat (limited to '2022/07')
-rw-r--r--2022/07/a.rs12
-rw-r--r--2022/07/b.rs13
-rw-r--r--2022/07/common.rs130
3 files changed, 155 insertions, 0 deletions
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 @@
1mod common;
2use common::*;
3
4fn main() {
5 let fs = FileSystem::build_from_stdin();
6 let sum: usize = fs.iter()
7 .filter(|f| matches!(f.kind, FileType::Directory(_)))
8 .map(|f| f.real_size(&fs))
9 .filter(|s| *s <= 100000)
10 .sum();
11 println!("{sum}");
12}
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 @@
1mod common;
2use common::*;
3
4fn main() {
5 let fs = FileSystem::build_from_stdin();
6 let remaining = 70000000 - fs[0].real_size(&fs);
7 let ds: usize = fs.iter()
8 .filter(|f| matches!(f.kind, FileType::Directory(_)))
9 .map(|f| f.real_size(&fs))
10 .filter(|s| *s + remaining >= 30000000)
11 .min().unwrap();
12 println!("{ds}");
13}
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 @@
1use std::ops;
2
3pub enum FileType {
4 File(usize),
5 Directory(Vec<usize>)
6}
7
8pub struct File {
9 pub kind: FileType,
10 name: String
11}
12
13impl File {
14 pub fn real_size(&self, fs: &FileSystem) -> usize {
15 match &self.kind {
16 FileType::File(s) => *s,
17 FileType::Directory(c) =>
18 c.iter().map(|x: &usize| fs[*x].real_size(&fs)).sum()
19 }
20 }
21}
22
23pub struct FileSystem {
24 files: Vec<File>
25}
26
27impl FileSystem {
28 fn new() -> Self {
29 Self {
30 files: vec![File {
31 kind: FileType::Directory(Vec::<usize>::new()),
32 name: String::from("/")
33 }]
34 }
35 }
36
37 pub fn build_from_stdin() -> Self {
38 let mut fs = FileSystem::new();
39 let mut path = Path::new();
40 let mut line = String::new();
41 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
42 if &line[..5] == "$ cd " {
43 exec_cd(&line[5..], &mut path, &fs);
44 } else if &line[..3] == "dir" {
45 fs.add_dir(&line[4..line.len()-1], path.last());
46 } else if line.as_bytes()[0] != '$' as u8 {
47 let i = line.find(' ').unwrap();
48 let size = line[0..i].parse::<usize>().unwrap();
49 fs.add_file(&line[i+1..line.len()-1], size, path.last());
50 }
51 line.clear();
52 }
53 fs
54 }
55
56 fn make_parent(&mut self, id: usize, parent: usize) {
57 let p = &mut self.files[parent];
58 if let FileType::Directory(v) = &mut p.kind {
59 v.push(id);
60 } else {
61 panic!("Parent is not a directory");
62 }
63 }
64
65 fn add_dir(&mut self, name: &str, parent: usize) {
66 let id = self.files.len();
67 self.files.push(
68 File {
69 kind: FileType::Directory(Vec::<usize>::new()),
70 name: String::from(name)
71 }
72 );
73 self.make_parent(id, parent);
74 }
75
76 fn add_file(&mut self, name: &str, size: usize, parent: usize) {
77 let id = self.files.len();
78 self.files.push(
79 File {
80 kind: FileType::File(size),
81 name: String::from(name)
82 }
83 );
84 self.make_parent(id, parent);
85 }
86
87 pub fn iter(&self) -> impl Iterator<Item = &File>{
88 self.files.iter()
89 }
90}
91
92impl ops::Index<usize> for FileSystem {
93 type Output = File;
94 fn index(&self, i: usize) -> &File {
95 &self.files[i]
96 }
97}
98
99struct Path {
100 stack: Vec<usize>
101}
102
103impl Path {
104 fn new() -> Self { Self { stack: vec![0] } } // 0 is the id of "/"
105 fn last(&self) -> usize { *self.stack.last().unwrap() }
106 fn clear(&mut self) { self.stack.drain(1..); }
107 fn pop(&mut self) { self.stack.pop(); }
108 fn push(&mut self, dir_id: usize) { self.stack.push(dir_id); }
109}
110
111fn exec_cd(line: &str, path: &mut Path, fs: &FileSystem) {
112 if line.as_bytes()[0] == '/' as u8 {
113 path.clear();
114 } else if &line[..2] == ".." {
115 path.pop();
116 } else {
117 let current_dir = &fs[path.last()];
118 if let FileType::Directory(children) = &current_dir.kind {
119 for c in children {
120 if fs[*c].name == &line[..line.len()-1] {
121 path.push(*c);
122 return;
123 }
124 }
125 } else {
126 panic!("Non-directory in path");
127 }
128 panic!("Directory not found in current path");
129 }
130}

Generated with cgit - Back to sebastiano.tronto.net