aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-10-16 18:08:53 +0200
committerThomas Schmucker <ts@its1.de>2025-10-16 18:08:53 +0200
commit5dde3837a6ecbd372b2d5db0b12969a4b7fbf4f7 (patch)
tree7c8817bcb739319fedfb40e1e5d1a1b2d578beef
parent7af390a45aee5133ae83114983f4d461d76a837b (diff)
downloadadvent-of-code-5dde3837a6ecbd372b2d5db0b12969a4b7fbf4f7.tar.gz
advent-of-code-5dde3837a6ecbd372b2d5db0b12969a4b7fbf4f7.tar.bz2
advent-of-code-5dde3837a6ecbd372b2d5db0b12969a4b7fbf4f7.zip
day 11, aoc 2016
-rw-r--r--2016/src/day10.cpp11
-rw-r--r--2016/src/day11.cpp232
-rw-r--r--makefile4
3 files changed, 242 insertions, 5 deletions
diff --git a/2016/src/day10.cpp b/2016/src/day10.cpp
index 7c1f4f9..851ad9d 100644
--- a/2016/src/day10.cpp
+++ b/2016/src/day10.cpp
@@ -1,3 +1,4 @@
1#include <filesystem>
1#include <fstream> 2#include <fstream>
2#include <iostream> 3#include <iostream>
3#include <map> 4#include <map>
@@ -9,6 +10,8 @@ using namespace std;
9 10
10using Sink = tuple<string, int>; 11using Sink = tuple<string, int>;
11 12
13namespace {
14
12vector<string> 15vector<string>
13split(const string& line, char sep) 16split(const string& line, char sep)
14{ 17{
@@ -23,7 +26,7 @@ split(const string& line, char sep)
23} 26}
24 27
25map<int, tuple<Sink, Sink, vector<int>>> 28map<int, tuple<Sink, Sink, vector<int>>>
26read_file(string_view filename) 29read_file(const filesystem::path& filename)
27{ 30{
28 fstream input{ filename }; 31 fstream input{ filename };
29 32
@@ -84,16 +87,18 @@ solve(map<int, tuple<Sink, Sink, vector<int>>> bots)
84 87
85 // part1 88 // part1
86 if ( chips.at(0) == 17 && chips.at(1) == 61 ) { 89 if ( chips.at(0) == 17 && chips.at(1) == 61 ) {
87 cout << id << endl; 90 cout << id << '\n';
88 } 91 }
89 92
90 chips.clear(); 93 chips.clear();
91 } 94 }
92 95
93 // part2 96 // part2
94 cout << outputs[0] * outputs[1] * outputs[2] << endl; 97 cout << outputs[0] * outputs[1] * outputs[2] << '\n';
95} 98}
96 99
100} // namespace
101
97int 102int
98main() 103main()
99{ 104{
diff --git a/2016/src/day11.cpp b/2016/src/day11.cpp
new file mode 100644
index 0000000..af3d2df
--- /dev/null
+++ b/2016/src/day11.cpp
@@ -0,0 +1,232 @@
1#include <fstream>
2#include <iostream>
3#include <map>
4#include <set>
5#include <sstream>
6#include <string>
7
8using namespace std;
9
10struct Item {
11 Item() = default;
12 Item(size_t chip_floor, size_t generator_floor) // NOLINT
13 : chip_floor_{ chip_floor }
14 , generator_floor_{ generator_floor }
15 {
16 }
17
18 size_t chip_floor_;
19 size_t generator_floor_;
20
21 bool operator<(const Item& rhs) const
22 {
23 if ( chip_floor_ != rhs.chip_floor_ ) {
24 return chip_floor_ < rhs.chip_floor_;
25 }
26 return generator_floor_ < rhs.generator_floor_;
27 }
28};
29
30struct State {
31 explicit State(const vector<Item>& items)
32 : items_{ items }
33 {
34 }
35
36 [[nodiscard]]
37 bool is_valid() const
38 {
39 for ( size_t i = 0; i != items_.size(); ++i ) {
40 const auto chip_floor = items_[i].chip_floor_; // Etage des Mikrochips
41 if ( chip_floor == items_[i].generator_floor_ ) {
42 continue; // Mikrochip ist mit seinem Generator zusammen
43 }
44 // Prüfe, ob ein fremder Generator auf derselben Etage ist
45 for ( size_t j = 0; j != items_.size(); ++j ) {
46 if ( j != i && chip_floor == items_[j].generator_floor_ ) {
47 return false; // Ungültig: Mikrochip mit fremdem Generator ohne eigenen Generator
48 }
49 }
50 }
51 return true;
52 }
53
54 [[nodiscard]]
55 bool is_goal() const
56 {
57 for ( const auto& item: items_ ) {
58 if ( item.chip_floor_ != 3 || item.generator_floor_ != 3 ) {
59 return false;
60 }
61 }
62 return elevator_ == 3;
63 }
64
65 bool operator<(const State& rhs) const
66 {
67 if ( elevator_ != rhs.elevator_ ) {
68 return elevator_ < rhs.elevator_;
69 }
70 return items_ < rhs.items_;
71 }
72
73 size_t elevator_{};
74 vector<Item> items_;
75};
76
77namespace {
78
79set<string>
80split(const string& line, char sep)
81{
82 set<string> parts;
83 stringstream input{ line };
84
85 for ( string part; getline(input, part, sep); ) {
86 parts.insert(part);
87 }
88
89 for ( const auto& word: { "The", "a", "floor", "and", "contains", "microchip",
90 "microchip.", "microchip,", "generator", "generator.", "generator,", "first",
91 "second", "third", "fourth", "nothing", "relevant." } ) {
92 parts.erase(word);
93 }
94
95 return parts;
96}
97
98vector<Item>
99read_file(const filesystem::path& filename)
100{
101 fstream input{ filename };
102 map<string, Item> data;
103
104 auto is_microchip = [](string_view item) {
105 return item.ends_with("-compatible");
106 };
107
108 string line;
109 for ( size_t floor = 0; getline(input, line); ++floor ) {
110 auto items = split(line, ' ');
111
112 for ( auto item: items ) {
113 if ( is_microchip(item) ) {
114 item = item.erase(item.find('-'));
115
116 data[item].chip_floor_ = floor;
117 }
118 else {
119 data[item].generator_floor_ = floor;
120 }
121 }
122 }
123
124 vector<Item> result;
125 result.reserve(data.size());
126 for ( const auto& item: data ) {
127 result.emplace_back(item.second);
128 }
129
130 return result;
131}
132
133int
134part1(const State& initial)
135{
136 queue<pair<State, int>> queue; // {Zustand, Schritte}
137 set<State> visited;
138
139 queue.emplace(initial, 0);
140 visited.insert(initial);
141
142 while ( !queue.empty() ) {
143 auto [current, steps] = queue.front();
144 queue.pop();
145
146 if ( current.is_goal() ) {
147 return steps;
148 }
149
150 // Mögliche Aufzugbewegungen: hoch oder runter
151 for ( int dir: { -1, 1 } ) {
152 auto new_elevator = current.elevator_ + size_t(dir);
153 if ( new_elevator < 0 || new_elevator > 3 ) {
154 continue;
155 }
156
157 // Wähle 1 oder 2 Objekte
158 vector<size_t> items_on_floor;
159 for ( size_t i = 0; i < current.items_.size(); ++i ) {
160 if ( current.items_[i].generator_floor_ == current.elevator_ ) {
161 items_on_floor.emplace_back(i * 2); // Generator
162 }
163 if ( current.items_[i].chip_floor_ == current.elevator_ ) {
164 items_on_floor.emplace_back((i * 2) + 1); // Mikrochip
165 }
166 }
167
168 // Alle Kombinationen von 1 oder 2 Objekten
169 for ( size_t i = 0; i < items_on_floor.size(); ++i ) {
170 // 1 Objekt
171 State next = current;
172 next.elevator_ = new_elevator;
173 auto item = items_on_floor[i];
174 if ( item % 2 == 0 ) {
175 next.items_[item / 2].generator_floor_ = new_elevator; // Generator
176 }
177 else {
178 next.items_[item / 2].chip_floor_ = new_elevator; // Mikrochip
179 }
180 if ( next.is_valid() && !visited.contains(next) ) {
181 visited.emplace(next);
182 queue.emplace(next, steps + 1);
183 }
184
185 // 2 Objekte
186 for ( size_t j = i + 1; j < items_on_floor.size(); ++j ) {
187 State next2 = current;
188 next2.elevator_ = new_elevator;
189 auto item1 = items_on_floor[i];
190 auto item2 = items_on_floor[j];
191 if ( item1 % 2 == 0 ) {
192 next2.items_[item1 / 2].generator_floor_ = new_elevator;
193 }
194 else {
195 next2.items_[item1 / 2].chip_floor_ = new_elevator;
196 }
197 if ( item2 % 2 == 0 ) {
198 next2.items_[item2 / 2].generator_floor_ = new_elevator;
199 }
200 else {
201 next2.items_[item2 / 2].chip_floor_ = new_elevator;
202 }
203 if ( next2.is_valid() && !visited.contains(next2) ) {
204 visited.insert(next2);
205 queue.emplace(next2, steps + 1);
206 }
207 }
208 }
209 }
210 }
211 return -1; // Keine Lösung gefunden
212}
213
214int
215part2(State initial)
216{
217 initial.items_.emplace_back(0, 0);
218 initial.items_.emplace_back(0, 0);
219 return part1(initial);
220}
221
222} // namespace
223
224int
225main()
226{
227 auto floors = read_file("data/day11.txt");
228 State state{ floors };
229
230 cout << "Part1: " << part1(state) << '\n';
231 cout << "Part2: " << part2(state) << '\n';
232}
diff --git a/makefile b/makefile
index ffd0a23..6efd32d 100644
--- a/makefile
+++ b/makefile
@@ -37,14 +37,14 @@ all: $(patsubst 2015/src/%.cpp,2015/bin/%,$(wildcard 2015/src/*.cpp)) \
37 c++ $(CPPFLAGS) $^ -o $@ 37 c++ $(CPPFLAGS) $^ -o $@
38 38
392023/bin/day24: 2023/src/day24.cpp | 2023/bin 392023/bin/day24: 2023/src/day24.cpp | 2023/bin
40 c++ $(CPPFLAGS) -Wno-sign-conversion -I/usr/local/include $^ -L/usr/local/lib -lz3 -o $@ 40 c++ $(CPPFLAGS) -Wno-sign-conversion $^ -lz3 -o $@
41 41
42# 2024 42# 2024
432024/bin/%: 2024/src/%.cpp | 2024/bin 432024/bin/%: 2024/src/%.cpp | 2024/bin
44 c++ $(CPPFLAGS) $^ -o $@ 44 c++ $(CPPFLAGS) $^ -o $@
45 45
462024/bin/day13-z3: 2024/src/day13-z3.cpp | 2024/bin 462024/bin/day13-z3: 2024/src/day13-z3.cpp | 2024/bin
47 c++ $(CPPFLAGS) $^ -L/usr/local/lib -lz3 -o $@ 47 c++ $(CPPFLAGS) $^ -lz3 -o $@
48 48
49clean: 49clean:
50 rm -rf 2015/bin 2016/bin 2020/bin 2022/bin 2023/bin 2024/bin 50 rm -rf 2015/bin 2016/bin 2020/bin 2022/bin 2023/bin 2024/bin