Skip to content

Commit 32b2198

Browse files
committed
Add 2017 day 21 cpp
1 parent 24ce9b9 commit 32b2198

File tree

4 files changed

+461
-2
lines changed

4 files changed

+461
-2
lines changed

2017/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This folder contains solutions to each of the problems in Advent of Code 2017 in
44

55
#### Notes ####
66
* There are multiple sample puzzle inputs for some days. Modify the sample input file appropriately before using it.
7-
* There are places where the sample input and input have different parameters (for e.g. day 16, where n = 5 and 16 respectively). Modify the .cpp file appropriately before using it.
7+
* There are places where the sample input and input have different parameters (for e.g. day 16, where n = 5 and 16 respectively and day 18, where iterations = 2 and 5(18) respectively). Modify the .cpp file appropriately before using it.
88

99
|Puzzle|C++ Solutions|Input|Sample Input|Puzzle page with solutions|
1010
|:---:|:---:|:---:|:---:|:---:|
@@ -28,12 +28,12 @@ This folder contains solutions to each of the problems in Advent of Code 2017 in
2828
| <nobr> [Day 18: Duet](https://adventofcode.com/2017/day/18) </nobr> | <nobr> [Part 1](/2017/cpp/day_18a.cpp) [Part 2](/2017/cpp/day_18b.cpp) </nobr> |[Link](/2017/input/day_18_input)|[Link](/2017/sample_input/day_18_sample_input)|[Link](/2017/puzzles/day_18_puzzle)|
2929
| <nobr> [Day 19: A Series of Tubes](https://adventofcode.com/2017/day/19) </nobr> | <nobr> [Part 1](/2017/cpp/day_19a.cpp) [Part 2](/2017/cpp/day_19b.cpp) </nobr> |[Link](/2017/input/day_19_input)|[Link](/2017/sample_input/day_19_sample_input)|[Link](/2017/puzzles/day_19_puzzle)|
3030
| <nobr> [Day 20: Particle Swarm](https://adventofcode.com/2017/day/20) </nobr> | <nobr> [Part 1](/2017/cpp/day_20a.cpp) [Part 2](/2017/cpp/day_20b.cpp) </nobr> |[Link](/2017/input/day_20_input)|[Link](/2017/sample_input/day_20_sample_input)|[Link](/2017/puzzles/day_20_puzzle)|
31+
| <nobr> [Day 21: Fractal Art](https://adventofcode.com/2017/day/21) </nobr> | <nobr> [Part 1](/2017/cpp/day_21a.cpp) [Part 2](/2017/cpp/day_21b.cpp) </nobr> |[Link](/2017/input/day_21_input)|[Link](/2017/sample_input/day_21_sample_input)|[Link](/2017/puzzles/day_21_puzzle)|
3132

3233
#### TODO ####
3334

3435
|Puzzle|C++ Solutions|Input|Sample Input|Puzzle page with solutions|
3536
|:---:|:---:|:---:|:---:|:---:|
36-
| <nobr> [Day 21: ](https://adventofcode.com/2017/day/21) </nobr> | <nobr> [Part 1](/2017/cpp/day_21a.cpp) [Part 2](/2017/cpp/day_21b.cpp) </nobr> |[Link](/2017/input/day_21_input)|[Link](/2017/sample_input/day_21_sample_input)|[Link](/2017/puzzles/day_21_puzzle)|
3737
| <nobr> [Day 22: ](https://adventofcode.com/2017/day/22) </nobr> | <nobr> [Part 1](/2017/cpp/day_22a.cpp) [Part 2](/2017/cpp/day_22b.cpp) </nobr> |[Link](/2017/input/day_22_input)|[Link](/2017/sample_input/day_22_sample_input)|[Link](/2017/puzzles/day_22_puzzle)|
3838
| <nobr> [Day 23: ](https://adventofcode.com/2017/day/23) </nobr> | <nobr> [Part 1](/2017/cpp/day_23a.cpp) [Part 2](/2017/cpp/day_23b.cpp) </nobr> |[Link](/2017/input/day_23_input)|[Link](/2017/sample_input/day_23_sample_input)|[Link](/2017/puzzles/day_23_puzzle)|
3939
| <nobr> [Day 24: ](https://adventofcode.com/2017/day/24) </nobr> | <nobr> [Part 1](/2017/cpp/day_24a.cpp) [Part 2](/2017/cpp/day_24b.cpp) </nobr> |[Link](/2017/input/day_24_input)|[Link](/2017/sample_input/day_24_sample_input)|[Link](/2017/puzzles/day_24_puzzle)|

2017/cpp/day_21a.cpp

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#include <algorithm>
2+
#include <fstream>
3+
#include <iostream>
4+
#include <string>
5+
#include <limits>
6+
#include <unordered_map>
7+
#include <unordered_set>
8+
#include <vector>
9+
#include <regex>
10+
#include <cassert>
11+
#include <cmath>
12+
13+
struct Coord2D {
14+
int row;
15+
int col;
16+
17+
Coord2D(const int row = 0, const int col = 0) : row(row) , col(col) {}
18+
19+
Coord2D operator + (const Coord2D& c) const {
20+
Coord2D ans;
21+
ans.row = row + c.row;
22+
ans.col = col + c.col;
23+
return ans;
24+
}
25+
26+
bool operator == (const Coord2D& c) const {
27+
return row == c.row && col == c.col;
28+
}
29+
30+
31+
32+
Coord2D operator - (const Coord2D& c) const {
33+
Coord2D ans;
34+
ans.row = row - c.row;
35+
ans.col = col - c.col;
36+
return ans;
37+
}
38+
39+
Coord2D operator += (const Coord2D& c) {
40+
row += c.row;
41+
col += c.col;
42+
return *this;
43+
}
44+
};
45+
46+
struct hasher {
47+
std::size_t operator()(const Coord2D& c) const {
48+
return 1000000 * c.row + c.col;
49+
}
50+
};
51+
52+
void print_pattern(const std::unordered_map<Coord2D, char, hasher>& pattern) {
53+
const int dim = std::sqrt(pattern.size());
54+
for (int row = 0; row < dim; row++) {
55+
for (int col = 0; col < dim; col++) {
56+
std::cout << pattern.at(Coord2D(row,col));
57+
}
58+
std::cout << '\n';
59+
}
60+
std::cout << '\n';
61+
}
62+
63+
int count_on_in_pattern(const std::unordered_map<Coord2D, char, hasher>& pattern) {
64+
const int dim = std::sqrt(pattern.size());
65+
int count = 0;
66+
for (int row = 0; row < dim; row++) {
67+
for (int col = 0; col < dim; col++) {
68+
if(pattern.at(Coord2D(row,col)) == '#') count++;
69+
}
70+
}
71+
return count;
72+
}
73+
74+
75+
std::string pattern_to_string(const std::unordered_map<Coord2D, char, hasher>& map) {
76+
std::string ans = "";
77+
const int n = (map.size() == 4) ? 2 : 3;
78+
for (int row = 0; row < n; row++) {
79+
for (int col = 0; col < n; col++) {
80+
ans += map.at(Coord2D(row, col));
81+
}
82+
if (row != n - 1) ans += '/';
83+
}
84+
return ans;
85+
}
86+
87+
std::unordered_map<Coord2D, char, hasher> string_to_pattern(const std::string& s) {
88+
std::unordered_map<Coord2D, char, hasher> map;
89+
int n = 0;
90+
if(s.size() == 5) {
91+
n = 2;
92+
} else if(s.size() == 11) {
93+
n = 3;
94+
} else if(s.size() == 19) {
95+
n = 4;
96+
}
97+
for (int row = 0; row < n; row++) {
98+
for (int col = 0; col < n; col++) {
99+
map[Coord2D(row, col)] = s[row * (n + 1) + col]; // n+1 to include the '/'
100+
}
101+
}
102+
return map;
103+
}
104+
105+
std::unordered_map<Coord2D, char, hasher> rotate_pattern(const std::unordered_map<Coord2D, char, hasher>& map) {
106+
std::unordered_map<Coord2D, char, hasher> ans;
107+
const int n = map.size() == 4 ? 2 :3;
108+
for (int row = 0; row < n; row++) {
109+
for (int col = 0; col < n; col++) {
110+
ans[Coord2D(row, col)] = map.at(Coord2D(n - col - 1, row));
111+
// std::cout << ans[Coord2D(row, col)];
112+
}
113+
// std::cout << '\n';
114+
}
115+
// std::cout << '\n';
116+
return ans;
117+
}
118+
119+
std::unordered_map<Coord2D, char, hasher> flip_pattern(const std::unordered_map<Coord2D, char, hasher>& map) {
120+
std::unordered_map<Coord2D, char, hasher> ans;
121+
const int n = map.size() == 4 ? 2 :3;
122+
for (int row = 0; row < n; row++) {
123+
for (int col = 0; col < n; col++) {
124+
ans[Coord2D(n - row - 1, col)] = map.at(Coord2D(row, col));
125+
}
126+
}
127+
return ans;
128+
}
129+
130+
int main(int argc, char* argv[]) {
131+
const std::string input = (argc > 1) ? argv[1] : "../input/day_21_input" ;
132+
std::ifstream file(input);
133+
std::string line;
134+
const std::regex regex_pattern(R"(([#./]+) => ([#./]+))");
135+
std::unordered_map<std::string, std::unordered_map<Coord2D, char, hasher>> rules;
136+
while(std::getline(file, line)) {
137+
std::smatch match;
138+
std::regex_search(line, match, regex_pattern);
139+
const std::string input_str = match[1];
140+
// std::cout << input_str << '\n';
141+
// std::cout << pattern_to_string(string_to_pattern(input_str)) << '\n';
142+
assert(input_str == pattern_to_string(string_to_pattern(input_str)));
143+
const auto output_pattern_str = match[2];
144+
// std::cout << output_pattern_str << '\n';
145+
const auto output_pattern = string_to_pattern(output_pattern_str);
146+
auto pattern = string_to_pattern(input_str);
147+
148+
// rules[pattern_to_string(pattern)] = output_pattern;
149+
// rules[pattern_to_string(flip_pattern(pattern))] = output_pattern;
150+
for (int i = 0; i < 4; i++) {
151+
pattern = rotate_pattern(pattern);
152+
rules[pattern_to_string(pattern)] = output_pattern;
153+
rules[pattern_to_string(flip_pattern(pattern))] = output_pattern;
154+
}
155+
}
156+
157+
// .#.
158+
// ..#
159+
// ###
160+
std::unordered_map<Coord2D, char, hasher> pattern;
161+
std::unordered_map<Coord2D, char, hasher> new_pattern;
162+
pattern[Coord2D(0,0)] = '.';
163+
pattern[Coord2D(0,1)] = '#';
164+
pattern[Coord2D(0,2)] = '.';
165+
pattern[Coord2D(1,0)] = '.';
166+
pattern[Coord2D(1,1)] = '.';
167+
pattern[Coord2D(1,2)] = '#';
168+
pattern[Coord2D(2,0)] = '#';
169+
pattern[Coord2D(2,1)] = '#';
170+
pattern[Coord2D(2,2)] = '#';
171+
172+
int n_parts = 0;
173+
int n = 0;
174+
int iterations = 0;
175+
// Fix (0,0)
176+
for (int iterations = 0; iterations < 5; iterations++) {
177+
const int dim = std::sqrt(pattern.size());
178+
179+
if (dim % 2 == 0) {
180+
// std::cout << __LINE__ << '\n';
181+
n_parts = dim/2;
182+
n = 2;
183+
} else if (dim % 3 == 0) {
184+
// std::cout << __LINE__ << '\n';
185+
n_parts = dim/3;
186+
n = 3;
187+
} else {
188+
std::cout << "Weird" << '\n';
189+
std::cout << dim << '\n';
190+
exit(0);
191+
}
192+
// std::cout << "dim == " << dim << '\n';
193+
// std::cout << "n_parts == " << n_parts << '\n';
194+
// std::cout << "n == " << n << '\n';
195+
// std::cout << "Pattern: " <<'\n';
196+
// print_pattern(pattern);
197+
for (int parts_row = 0; parts_row < n_parts; parts_row++) {
198+
const int row = n * parts_row;
199+
for (int parts_col = 0; parts_col < n_parts; parts_col++) {
200+
const int col = n * parts_col;
201+
std::unordered_map<Coord2D, char, hasher> mini_pattern;
202+
for (int i = 0; i < n; i++) {
203+
for (int j = 0; j < n; j++) {
204+
mini_pattern[Coord2D(i,j)]= pattern[Coord2D(row + i, col + j)];
205+
}
206+
}
207+
// std::cout << "Mini pattern: " <<'\n';
208+
// print_pattern(mini_pattern);
209+
const auto new_mini_pattern = rules.at(pattern_to_string(mini_pattern));
210+
// std::cout << "New mini pattern: " <<'\n';
211+
// print_pattern(new_mini_pattern);
212+
for (int i = 0; i < n + 1; i++) {
213+
for (int j = 0; j < n + 1; j++) {
214+
new_pattern[Coord2D((n + 1)* parts_row + i, (n + 1) * parts_col + j)] = new_mini_pattern.at(Coord2D(i,j));
215+
}
216+
}
217+
}
218+
}
219+
std::swap(pattern, new_pattern);
220+
// std::cout << count_on_in_pattern(pattern) <<'\n';
221+
}
222+
// std::cout << "Pattern: " <<'\n';
223+
// print_pattern(pattern);
224+
std::cout << count_on_in_pattern(pattern) <<'\n';
225+
return 0;
226+
}

0 commit comments

Comments
 (0)