Line data Source code
1 : #include "Puzzle.h"
2 : #include "InputDir.h"
3 : #include "PuzzleImpl.h"
4 : #include "StringUtils.h"
5 :
6 : #include <libassert/assert.hpp>
7 :
8 : #include <format>
9 : #include <map>
10 : #include <string>
11 : #include <string_view>
12 :
13 11628 : std::string const Puzzle::name() const { return std::format("{}_{}", year(), day()); }
14 :
15 : using FactoryFunction = std::unique_ptr<Puzzle> (*)();
16 :
17 11781 : static std::map<Puzzle::Year, std::map<Puzzle::Day, FactoryFunction>> &getFactoryFunctions() {
18 11781 : static std::map<Puzzle::Year, std::map<Puzzle::Day, FactoryFunction>> factoryFunctions;
19 11781 : return factoryFunctions;
20 11781 : }
21 :
22 : static bool registerConcretePuzzle(Puzzle::Year const y, Puzzle::Day const d,
23 11628 : FactoryFunction const f) {
24 11628 : auto &factoryFunctions = getFactoryFunctions();
25 :
26 11628 : auto [it, yearInserted] = factoryFunctions.try_emplace(y);
27 11628 : auto [it2, dayInserted] = it->second.emplace(d, f);
28 :
29 11628 : return dayInserted;
30 11628 : }
31 :
32 11628 : Puzzle::Puzzle(Year const year_, Day const day_) : _year(year_), _day(day_) {
33 11628 : auto const dir = std::filesystem::path(inputDir) / std::format("{:0>4}/{:0>2}", year_, day_);
34 11628 : _input = readFileAsString(dir / "Input.txt");
35 11628 : _solutionPart1 = readFileAsString(dir / "SolutionPart1.txt");
36 11628 : _solutionPart2 = readFileAsString(dir / "SolutionPart2.txt");
37 11628 : }
38 :
39 : template <int YEAR, unsigned DAY> class ConcretePuzzle final : public Puzzle {
40 : public:
41 11628 : ConcretePuzzle() : Puzzle(Year(YEAR), Day(DAY)) {}
42 :
43 76 : [[nodiscard]] std::string runPart1(std::string_view const input) const final {
44 76 : return solvePart1<YEAR, DAY>(input);
45 76 : }
46 76 : [[nodiscard]] std::string runPart2(std::string_view const input) const final {
47 76 : return solvePart2<YEAR, DAY>(input);
48 76 : }
49 :
50 11628 : static std::unique_ptr<Puzzle> create() { return std::make_unique<ConcretePuzzle>(); }
51 : static inline bool const registered = registerConcretePuzzle(Year(YEAR), Day(DAY), create);
52 : };
53 :
54 : template class ConcretePuzzle<2015, 1>;
55 : template class ConcretePuzzle<2015, 2>;
56 : template class ConcretePuzzle<2015, 3>;
57 : template class ConcretePuzzle<2015, 4>;
58 : template class ConcretePuzzle<2015, 5>;
59 : template class ConcretePuzzle<2015, 6>;
60 :
61 : template class ConcretePuzzle<2019, 2>;
62 : template class ConcretePuzzle<2019, 5>;
63 : template class ConcretePuzzle<2019, 7>;
64 : template class ConcretePuzzle<2019, 9>;
65 : template class ConcretePuzzle<2019, 11>;
66 : template class ConcretePuzzle<2019, 13>;
67 : template class ConcretePuzzle<2019, 15>;
68 : template class ConcretePuzzle<2019, 17>;
69 :
70 : template class ConcretePuzzle<2022, 1>;
71 : template class ConcretePuzzle<2022, 2>;
72 : template class ConcretePuzzle<2022, 3>;
73 : template class ConcretePuzzle<2022, 4>;
74 : template class ConcretePuzzle<2022, 8>;
75 :
76 : template class ConcretePuzzle<2023, 1>;
77 : template class ConcretePuzzle<2023, 2>;
78 : template class ConcretePuzzle<2023, 3>;
79 : template class ConcretePuzzle<2023, 4>;
80 : template class ConcretePuzzle<2023, 5>;
81 : template class ConcretePuzzle<2023, 6>;
82 : template class ConcretePuzzle<2023, 7>;
83 : template class ConcretePuzzle<2023, 8>;
84 : template class ConcretePuzzle<2023, 9>;
85 : template class ConcretePuzzle<2023, 10>;
86 : template class ConcretePuzzle<2023, 11>;
87 : template class ConcretePuzzle<2023, 12>;
88 : template class ConcretePuzzle<2023, 13>;
89 : template class ConcretePuzzle<2023, 14>;
90 : template class ConcretePuzzle<2023, 15>;
91 : template class ConcretePuzzle<2023, 16>;
92 : template class ConcretePuzzle<2023, 17>;
93 : template class ConcretePuzzle<2023, 18>;
94 : template class ConcretePuzzle<2023, 19>;
95 : template class ConcretePuzzle<2023, 20>;
96 : template class ConcretePuzzle<2023, 21>;
97 : template class ConcretePuzzle<2023, 22>;
98 : template class ConcretePuzzle<2023, 23>;
99 : template class ConcretePuzzle<2023, 24>;
100 : template class ConcretePuzzle<2023, 25>;
101 :
102 : template class ConcretePuzzle<2024, 1>;
103 : template class ConcretePuzzle<2024, 2>;
104 : template class ConcretePuzzle<2024, 3>;
105 : template class ConcretePuzzle<2024, 4>;
106 : template class ConcretePuzzle<2024, 5>;
107 : template class ConcretePuzzle<2024, 6>;
108 : template class ConcretePuzzle<2024, 7>;
109 : template class ConcretePuzzle<2024, 8>;
110 : template class ConcretePuzzle<2024, 9>;
111 : template class ConcretePuzzle<2024, 10>;
112 : template class ConcretePuzzle<2024, 11>;
113 : template class ConcretePuzzle<2024, 12>;
114 : template class ConcretePuzzle<2024, 13>;
115 : template class ConcretePuzzle<2024, 14>;
116 : template class ConcretePuzzle<2024, 15>;
117 : template class ConcretePuzzle<2024, 16>;
118 : template class ConcretePuzzle<2024, 17>;
119 : template class ConcretePuzzle<2024, 18>;
120 : template class ConcretePuzzle<2024, 19>;
121 : template class ConcretePuzzle<2024, 20>;
122 : template class ConcretePuzzle<2024, 22>;
123 : template class ConcretePuzzle<2024, 23>;
124 : template class ConcretePuzzle<2024, 25>;
125 :
126 : template class ConcretePuzzle<2025, 1>;
127 : template class ConcretePuzzle<2025, 2>;
128 : template class ConcretePuzzle<2025, 3>;
129 : template class ConcretePuzzle<2025, 4>;
130 : template class ConcretePuzzle<2025, 5>;
131 : template class ConcretePuzzle<2025, 6>;
132 : template class ConcretePuzzle<2025, 7>;
133 : template class ConcretePuzzle<2025, 8>;
134 : template class ConcretePuzzle<2025, 10>;
135 :
136 0 : Puzzle::Year Puzzle::latestYear() {
137 0 : auto const &factoryFunctions = getFactoryFunctions();
138 0 : ASSUME(!factoryFunctions.empty());
139 0 : return std::prev(factoryFunctions.end())->first;
140 0 : }
141 :
142 0 : Puzzle::Day Puzzle::latestDay(Year const year) {
143 0 : auto const &factoryFunctions = getFactoryFunctions();
144 0 : auto it = factoryFunctions.find(year);
145 0 : ASSUME(it != factoryFunctions.end());
146 0 : ASSUME(!it->second.empty());
147 0 : return std::prev(it->second.end())->first;
148 0 : };
149 :
150 0 : std::unique_ptr<Puzzle> Puzzle::create(Year const year, Day const day) {
151 0 : auto const &factoryFunctions = getFactoryFunctions();
152 0 : auto it = factoryFunctions.find(year);
153 0 : if (it == factoryFunctions.end())
154 0 : return nullptr;
155 0 : auto it2 = it->second.find(day);
156 0 : if (it2 == it->second.end())
157 0 : return nullptr;
158 0 : return (it2->second)();
159 0 : }
160 :
161 153 : std::vector<std::unique_ptr<Puzzle>> Puzzle::createAll() {
162 153 : auto const &factoryFunctions = getFactoryFunctions();
163 153 : std::vector<std::unique_ptr<Puzzle>> puzzles;
164 :
165 153 : for (auto const &[year, dayMap] : factoryFunctions)
166 918 : for (auto const &[day, func] : dayMap)
167 11628 : puzzles.push_back(func());
168 :
169 153 : return puzzles;
170 153 : }
171 :
172 0 : std::vector<std::unique_ptr<Puzzle>> Puzzle::createAll(Year const year) {
173 0 : auto const &factoryFunctions = getFactoryFunctions();
174 0 : std::vector<std::unique_ptr<Puzzle>> puzzles;
175 :
176 0 : auto it = factoryFunctions.find(year);
177 0 : if (it != factoryFunctions.end()) {
178 0 : for (auto [day, func] : it->second)
179 0 : puzzles.push_back(func());
180 0 : }
181 :
182 0 : return puzzles;
183 0 : }
|