Line data Source code
1 : #include "Puzzle.h"
2 : #include "InputDir.h"
3 : #include "PuzzleImpl.h"
4 :
5 : #include <libassert/assert.hpp>
6 :
7 : #include <format>
8 : #include <map>
9 : #include <string>
10 : #include <string_view>
11 :
12 9045 : std::string const Puzzle::name() const { return std::format("{}_{}", year(), day()); }
13 :
14 : using FactoryFunction = std::unique_ptr<Puzzle> (*)();
15 :
16 9180 : static std::map<Puzzle::Year, std::map<Puzzle::Day, FactoryFunction>> &getFactoryFunctions() {
17 9180 : static std::map<Puzzle::Year, std::map<Puzzle::Day, FactoryFunction>> factoryFunctions;
18 9180 : return factoryFunctions;
19 9180 : }
20 :
21 : static bool registerConcretePuzzle(Puzzle::Year const y, Puzzle::Day const d,
22 9045 : FactoryFunction const f) {
23 9045 : auto &factoryFunctions = getFactoryFunctions();
24 :
25 9045 : auto [it, yearInserted] = factoryFunctions.try_emplace(y);
26 9045 : auto [it2, dayInserted] = it->second.emplace(d, f);
27 :
28 9045 : return dayInserted;
29 9045 : }
30 :
31 : template <int YEAR, unsigned DAY, size_t SOLUTION_PART1, size_t SOLUTION_PART2>
32 : class LegacyConcretePuzzle final : public Puzzle {
33 : public:
34 : LegacyConcretePuzzle()
35 8505 : : Puzzle(Year(YEAR), Day(DAY),
36 8505 : std::filesystem::path(inputDir) / std::to_string(YEAR) /
37 8505 : std::filesystem::path(std::format("Day{:0>2}.txt", DAY))),
38 8505 : _solutionPart1(std::to_string(SOLUTION_PART1)),
39 8505 : _solutionPart2(std::to_string(SOLUTION_PART2)) {}
40 :
41 63 : [[nodiscard]] std::string runPart1(std::string_view const input) const final {
42 63 : return std::to_string(part1<YEAR, DAY>(input));
43 63 : }
44 63 : [[nodiscard]] std::string runPart2(std::string_view const input) const final {
45 63 : return std::to_string(part2<YEAR, DAY>(input));
46 63 : }
47 :
48 63 : [[nodiscard]] std::string_view solutionPart1() const final { return _solutionPart1; };
49 63 : [[nodiscard]] std::string_view solutionPart2() const final { return _solutionPart2; };
50 :
51 8505 : static std::unique_ptr<Puzzle> create() { return std::make_unique<LegacyConcretePuzzle>(); }
52 : static inline bool const registered = registerConcretePuzzle(Year(YEAR), Day(DAY), create);
53 :
54 : std::string _solutionPart1;
55 : std::string _solutionPart2;
56 : };
57 :
58 : template <int YEAR, unsigned DAY> class ConcretePuzzle final : public Puzzle {
59 : public:
60 : ConcretePuzzle()
61 540 : : Puzzle(Year(YEAR), Day(DAY),
62 540 : std::filesystem::path(inputDir) / std::to_string(YEAR) /
63 540 : std::filesystem::path(std::format("Day{:0>2}.txt", DAY))) {}
64 :
65 4 : [[nodiscard]] std::string runPart1(std::string_view const input) const final {
66 4 : return solvePart1<YEAR, DAY>(input);
67 4 : }
68 4 : [[nodiscard]] std::string runPart2(std::string_view const input) const final {
69 4 : return solvePart2<YEAR, DAY>(input);
70 4 : }
71 :
72 4 : [[nodiscard]] std::string_view solutionPart1() const final { return solution1<YEAR, DAY>(); };
73 4 : [[nodiscard]] std::string_view solutionPart2() const final { return solution2<YEAR, DAY>(); };
74 :
75 540 : static std::unique_ptr<Puzzle> create() { return std::make_unique<ConcretePuzzle>(); }
76 : static inline bool const registered = registerConcretePuzzle(Year(YEAR), Day(DAY), create);
77 : };
78 :
79 : template class LegacyConcretePuzzle<2015, 1, 138, 1771>;
80 : template class LegacyConcretePuzzle<2015, 2, 1586300, 3737498>;
81 : template class LegacyConcretePuzzle<2015, 3, 2081, 2341>;
82 : template class LegacyConcretePuzzle<2015, 4, 117946, 3938038>;
83 : template class LegacyConcretePuzzle<2015, 5, 238, 69>;
84 : template class LegacyConcretePuzzle<2015, 6, 377891, 14110788>;
85 :
86 : template class LegacyConcretePuzzle<2019, 2, 6327510, 4112>;
87 : template class LegacyConcretePuzzle<2019, 5, 11933517, 10428568>;
88 : template class LegacyConcretePuzzle<2019, 7, 212460, 21844737>;
89 : template class LegacyConcretePuzzle<2019, 9, 2870072642, 58534>;
90 : template class LegacyConcretePuzzle<2019, 11, 2172, 248>;
91 : template class LegacyConcretePuzzle<2019, 13, 228, 10776>;
92 : template class LegacyConcretePuzzle<2019, 15, 252, 350>;
93 : template class LegacyConcretePuzzle<2019, 17, 5724, 0>;
94 :
95 : template class LegacyConcretePuzzle<2022, 1, 67027, 197291>;
96 : template class LegacyConcretePuzzle<2022, 2, 14531, 11258>;
97 : template class LegacyConcretePuzzle<2022, 3, 7674, 2805>;
98 : template class LegacyConcretePuzzle<2022, 4, 503, 827>;
99 : template class LegacyConcretePuzzle<2022, 8, 1688, 410400>;
100 :
101 : template class LegacyConcretePuzzle<2023, 1, 56465, 55902>;
102 : template class LegacyConcretePuzzle<2023, 2, 3035, 66027>;
103 : template class LegacyConcretePuzzle<2023, 3, 529618, 77509019>;
104 : template class LegacyConcretePuzzle<2023, 4, 21485, 11024379>;
105 : template class LegacyConcretePuzzle<2023, 5, 331445006, 6472060>;
106 : template class LegacyConcretePuzzle<2023, 6, 503424, 32607562>;
107 : template class LegacyConcretePuzzle<2023, 7, 252656917, 253499763>;
108 : template class LegacyConcretePuzzle<2023, 8, 12361, 18215611419223>;
109 : template class LegacyConcretePuzzle<2023, 9, 1972648895, 919>;
110 : template class LegacyConcretePuzzle<2023, 10, 6909, 461>;
111 : template class LegacyConcretePuzzle<2023, 11, 9681886, 791134099634>;
112 : template class LegacyConcretePuzzle<2023, 12, 6958, 6555315065024>;
113 : template class LegacyConcretePuzzle<2023, 13, 32035, 24847>;
114 : template class LegacyConcretePuzzle<2023, 14, 103333, 97241>;
115 : template class LegacyConcretePuzzle<2023, 15, 494980, 247933>;
116 : template class LegacyConcretePuzzle<2023, 16, 7951, 8148>;
117 : template class LegacyConcretePuzzle<2023, 17, 684, 822>;
118 : template class LegacyConcretePuzzle<2023, 18, 35401, 48020869073824>;
119 : template class LegacyConcretePuzzle<2023, 19, 397643, 132392981697081>;
120 : template class LegacyConcretePuzzle<2023, 20, 836127690, 240914003753369>;
121 : template class LegacyConcretePuzzle<2023, 21, 3716, 0>;
122 : template class LegacyConcretePuzzle<2023, 22, 505, 71002>;
123 : template class LegacyConcretePuzzle<2023, 23, 2246, 6622>;
124 : template class LegacyConcretePuzzle<2023, 24, 15262, 0>;
125 : template class LegacyConcretePuzzle<2023, 25, 543256, 0>;
126 :
127 : template class LegacyConcretePuzzle<2024, 1, 1603498, 25574739>;
128 : template class LegacyConcretePuzzle<2024, 2, 680, 710>;
129 : template class LegacyConcretePuzzle<2024, 3, 161289189, 83595109>;
130 : template class LegacyConcretePuzzle<2024, 4, 2547, 1939>;
131 : template class LegacyConcretePuzzle<2024, 5, 6242, 5169>;
132 : template class LegacyConcretePuzzle<2024, 6, 4722, 1602>;
133 : template class LegacyConcretePuzzle<2024, 7, 4998764814652, 37598910447546>;
134 : template class LegacyConcretePuzzle<2024, 8, 305, 1150>;
135 : template class LegacyConcretePuzzle<2024, 9, 6448989155953, 6476642796832>;
136 : template class LegacyConcretePuzzle<2024, 10, 611, 1380>;
137 : template class LegacyConcretePuzzle<2024, 11, 186175, 220566831337810>;
138 : template class LegacyConcretePuzzle<2024, 12, 1494342, 893676>;
139 : template class LegacyConcretePuzzle<2024, 13, 25629, 107487112929999>;
140 : template class LegacyConcretePuzzle<2024, 14, 216772608, 6888>;
141 : template class LegacyConcretePuzzle<2024, 15, 1448589, 1472235>;
142 : template class LegacyConcretePuzzle<2024, 16, 127520, 565>;
143 : template class ConcretePuzzle<2024, 17>;
144 : template class ConcretePuzzle<2024, 18>;
145 : template class LegacyConcretePuzzle<2024, 19, 369, 761826581538190>;
146 : template class LegacyConcretePuzzle<2024, 20, 1360, 1005476>;
147 : template class LegacyConcretePuzzle<2024, 22, 14869099597, 1717>;
148 : template class ConcretePuzzle<2024, 23>;
149 : template class ConcretePuzzle<2024, 25>;
150 :
151 0 : Puzzle::Year Puzzle::latestYear() {
152 0 : auto const &factoryFunctions = getFactoryFunctions();
153 0 : ASSUME(!factoryFunctions.empty());
154 0 : return std::prev(factoryFunctions.end())->first;
155 0 : }
156 :
157 0 : Puzzle::Day Puzzle::latestDay(Year const year) {
158 0 : auto const &factoryFunctions = getFactoryFunctions();
159 0 : auto it = factoryFunctions.find(year);
160 0 : ASSUME(it != factoryFunctions.end());
161 0 : ASSUME(!it->second.empty());
162 0 : return std::prev(it->second.end())->first;
163 0 : };
164 :
165 0 : std::unique_ptr<Puzzle> Puzzle::create(Year const year, Day const day) {
166 0 : auto const &factoryFunctions = getFactoryFunctions();
167 0 : auto it = factoryFunctions.find(year);
168 0 : if (it == factoryFunctions.end())
169 0 : return nullptr;
170 0 : auto it2 = it->second.find(day);
171 0 : if (it2 == it->second.end())
172 0 : return nullptr;
173 0 : return (it2->second)();
174 0 : }
175 :
176 135 : std::vector<std::unique_ptr<Puzzle>> Puzzle::createAll() {
177 135 : auto const &factoryFunctions = getFactoryFunctions();
178 135 : std::vector<std::unique_ptr<Puzzle>> puzzles;
179 :
180 135 : for (auto const &[year, dayMap] : factoryFunctions)
181 675 : for (auto const &[day, func] : dayMap)
182 9045 : puzzles.push_back(func());
183 :
184 135 : return puzzles;
185 135 : }
186 :
187 0 : std::vector<std::unique_ptr<Puzzle>> Puzzle::createAll(Year const year) {
188 0 : auto const &factoryFunctions = getFactoryFunctions();
189 0 : std::vector<std::unique_ptr<Puzzle>> puzzles;
190 :
191 0 : auto it = factoryFunctions.find(year);
192 0 : if (it != factoryFunctions.end()) {
193 0 : for (auto [day, func] : it->second)
194 0 : puzzles.push_back(func());
195 0 : }
196 :
197 0 : return puzzles;
198 0 : }
|