aboutsummaryrefslogtreecommitdiff
path: root/2018
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-11-16 22:56:16 +0100
committerThomas Schmucker <ts@its1.de>2025-11-16 22:56:16 +0100
commitf29300ee1b3a3bada6297aa9b017435a5da9b17d (patch)
tree177799822cbca3091e2c4528cd34ef7d974a20fd /2018
parent8c96639ec1f6757570510fc27f1c5fabece35eaf (diff)
downloadadvent-of-code-f29300ee1b3a3bada6297aa9b017435a5da9b17d.tar.gz
advent-of-code-f29300ee1b3a3bada6297aa9b017435a5da9b17d.tar.bz2
advent-of-code-f29300ee1b3a3bada6297aa9b017435a5da9b17d.zip
aoc 2018, days 12
Diffstat (limited to '2018')
-rw-r--r--2018/src/day12.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/2018/src/day12.cpp b/2018/src/day12.cpp
new file mode 100644
index 0000000..21d74b2
--- /dev/null
+++ b/2018/src/day12.cpp
@@ -0,0 +1,127 @@
1#include <filesystem>
2#include <fstream>
3#include <iostream>
4#include <map>
5#include <string>
6#include <unordered_set>
7
8using namespace std;
9
10namespace {
11
12using Plants = unordered_set<long>;
13using Rules = map<string, char>;
14using Puzzle = tuple<Plants, Rules>;
15
16Puzzle
17read_file(const filesystem::path& filename)
18{
19 fstream file{ filename };
20
21 string line;
22 getline(file, line);
23 line.erase(0, line.find(": ") + 2);
24
25 Plants plants;
26 for ( size_t idx = 0; idx != line.length(); ++idx ) {
27 if ( line.at(idx) == '#' ) {
28 plants.insert(static_cast<long>(idx));
29 }
30 }
31
32 getline(file, line);
33
34 Rules rules;
35 while ( getline(file, line) ) {
36 auto lhs = line.substr(0, 5);
37 auto rhs = line.substr(9);
38
39 rules[lhs] = rhs.at(0);
40 }
41
42 return { plants, rules };
43}
44
45Plants
46update(const Plants& current, const Rules& rules)
47{
48 auto [min, max] = ranges::minmax(current);
49
50 Plants next;
51
52 for ( auto i = min - 2; i <= max + 2; ++i ) {
53 string pattern;
54 pattern += current.contains(i - 2) ? '#' : '.';
55 pattern += current.contains(i - 1) ? '#' : '.';
56 pattern += current.contains(i) ? '#' : '.';
57 pattern += current.contains(i + 1) ? '#' : '.';
58 pattern += current.contains(i + 2) ? '#' : '.';
59
60 if ( rules.contains(pattern) && rules.at(pattern) == '#' ) {
61 next.insert(i);
62 }
63 }
64
65 return next;
66}
67
68void
69part1(const Puzzle& puzzle)
70{
71 auto [state, rules] = puzzle;
72
73 for ( int i = 0; i != 20; ++i ) {
74 state = update(state, rules);
75 }
76
77 long sum = 0;
78 for ( const auto pos: state ) {
79 sum += pos;
80 }
81 cout << "Part 1: " << sum << '\n';
82}
83
84void
85part2(const Puzzle& puzzle)
86{
87 auto [state, rules] = puzzle;
88
89 auto to_string = [&] {
90 string result;
91
92 auto [min, max] = ranges::minmax(state);
93 for ( auto pos = min; pos <= max; ++pos ) {
94 result += (state.contains(pos) ? '#' : '.');
95 }
96
97 return result;
98 };
99
100 unordered_set<string> seen;
101 for ( long shift = 50000000000;; --shift ) {
102 auto pattern = to_string();
103
104 if ( seen.contains(pattern) ) {
105 long sum = 0;
106 for ( const auto pos: state ) {
107 sum += pos + shift;
108 }
109 cout << "Part 2: " << sum << '\n';
110 return;
111 }
112
113 seen.insert(pattern);
114
115 state = update(state, rules);
116 }
117}
118
119} // namespace
120
121int
122main()
123{
124 auto puzzle = read_file("data/day12.txt");
125 part1(puzzle);
126 part2(puzzle);
127}