aboutsummaryrefslogtreecommitdiff
path: root/2022/src
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2024-05-01 13:00:14 +0200
committerThomas Schmucker <ts@its1.de>2024-05-01 13:00:14 +0200
commit4aaf38359e7323f75fd55d28a330c665bb81a477 (patch)
tree0adcd1c1ae6fb0b5abd77057fd46bc6ac9f6d22a /2022/src
parentb14dce43889ea4c9f0e2163f0aa5a0c3ca0a1377 (diff)
downloadadvent-of-code-4aaf38359e7323f75fd55d28a330c665bb81a477.tar.gz
advent-of-code-4aaf38359e7323f75fd55d28a330c665bb81a477.tar.bz2
advent-of-code-4aaf38359e7323f75fd55d28a330c665bb81a477.zip
day 7, advent of code 2022
Diffstat (limited to '2022/src')
-rw-r--r--2022/src/day07.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/2022/src/day07.cpp b/2022/src/day07.cpp
new file mode 100644
index 0000000..8a8decd
--- /dev/null
+++ b/2022/src/day07.cpp
@@ -0,0 +1,176 @@
1#include <cstdlib>
2#include <fstream>
3#include <iostream>
4#include <iterator>
5#include <map>
6#include <memory>
7#include <string>
8#include <vector>
9using namespace std;
10
11struct Node {
12 Node* parent = nullptr;
13
14 map<string, shared_ptr<Node>> sub;
15 map<string, long> files;
16};
17
18Node
19read_file(string_view filename, ostream& debug)
20{
21 Node root;
22 Node* current = &root;
23
24 fstream input{ filename };
25
26 string line;
27 getline(input, line);
28
29 while ( input ) {
30 if ( line.starts_with("$ ") ) {
31 if ( line == "$ cd /" ) {
32 debug << "cd root" << endl;
33 current = &root;
34 getline(input, line);
35 }
36 else if ( line == "$ cd .." ) {
37 debug << "cd one up" << endl;
38 current = current->parent;
39 getline(input, line);
40 }
41 else if ( line == "$ ls" ) {
42 debug << "list dir" << endl;
43 getline(input, line);
44
45 while ( input && !line.starts_with("$ ") ) {
46 if ( line.starts_with("dir ") ) {
47 const auto name = line.substr(4);
48 const auto node = make_shared<Node>();
49 node->parent = current;
50 current->sub[name] = node;
51 debug << "new subdir " << name << endl;
52 }
53 else {
54 const auto pos = line.find(' ');
55 const auto size = stol(line.substr(0, pos));
56 const auto name = line.substr(pos + 1);
57 current->files[name] = size;
58 debug << "new file " << name << " (" << size << ")" << endl;
59 }
60
61 getline(input, line);
62 }
63 }
64 else if ( line.starts_with("$ cd ") ) {
65 const auto dirname = line.substr(5);
66 current = current->sub[dirname].get();
67 debug << "cd into " << dirname << endl;
68 getline(input, line);
69 }
70 else {
71 cerr << "error in line: " << line << endl;
72 exit(EXIT_FAILURE);
73 }
74 }
75 else {
76 cerr << "error II in line: " << line << endl;
77 exit(EXIT_FAILURE);
78 }
79 }
80
81 return root;
82}
83
84void
85print(const Node& node, const string& indent = "")
86{
87 if ( node.parent == nullptr ) {
88 cout << indent << "/" << endl;
89 }
90
91 for ( const auto& [name, sub]: node.sub ) {
92 cout << indent << name << endl;
93 print(*sub.get(), indent + " ");
94 }
95
96 for ( const auto& [filename, filesize]: node.files ) {
97 cout << indent << filename << " (" << filesize << ")" << endl;
98 }
99}
100
101long
102part1_rec(const Node& node, long& all)
103{
104 long size = 0;
105
106 for ( const auto& [name, sub]: node.sub ) {
107 const auto sub_size = part1_rec(*sub.get(), all);
108 if ( sub_size <= 100000 ) {
109 all += sub_size;
110 }
111 size += sub_size;
112 }
113
114 for ( const auto& [filename, filesize]: node.files ) {
115 size += filesize;
116 }
117
118 return size;
119}
120
121void
122part1(const Node& node)
123{
124 long all = 0;
125 part1_rec(node, all);
126 cout << all << endl;
127}
128
129long
130part2_rec(const Node& node, vector<long>& sizes)
131{
132 long size = 0;
133
134 for ( const auto& [name, sub]: node.sub ) {
135 const auto sub_size = part2_rec(*sub.get(), sizes);
136 sizes.emplace_back(sub_size);
137 size += sub_size;
138 }
139
140 for ( const auto& [filename, filesize]: node.files ) {
141 size += filesize;
142 }
143
144 return size;
145}
146
147void
148part2(const Node& node)
149{
150 vector<long> sizes;
151 const auto needed = 30000000 - (70000000 - part2_rec(node, sizes));
152
153 vector<long> candidates;
154 copy_if(begin(sizes), end(sizes), back_inserter(candidates), [&](auto size) {
155 return size >= needed;
156 });
157
158 sort(begin(candidates), end(candidates));
159 cout << candidates[0] << endl;
160}
161
162int
163main()
164{
165 struct NullBuffer : public streambuf {
166 int overflow(int chr) final { return chr; }
167 };
168
169 NullBuffer nullBuffer;
170 ostream nullStream(&nullBuffer);
171
172 const auto node = read_file("data/day07.txt", nullStream);
173
174 part1(node);
175 part2(node);
176}