-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDay13.cpp
More file actions
34 lines (31 loc) · 1.1 KB
/
Day13.cpp
File metadata and controls
34 lines (31 loc) · 1.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "Solution.hpp"
#include "io.hpp"
#include <array>
#include <set>
using Point = std::array<int, 2>;
inline Point
operator+(const Point& p1, const Point& p2)
{
return {{std::get<0>(p1) + std::get<0>(p2), std::get<1>(p1) + std::get<1>(p2)}};
}
template <>
void
solve<Day13>(bool part2, std::istream& is, std::ostream& os)
{
const int LIMIT{50}, NUM{std::stoi(io::as_string(is))};
const std::array<Point, 4> DIRS{{{{-1, 0}}, {{1, 0}}, {{0, -1}}, {{0, 1}}}};
const Point INIT{{1, 1}}, TARGET{{39, 31}};
auto valid = [NUM](const Point& p) -> bool {
return p[1] >= 0 && p[0] >= 0 && !(__builtin_popcount(p[1] * (p[1] + 3) + p[0] * (p[1] + p[1] + p[0] + 1) + NUM) & 0x1);
};
int steps{0};
std::set<Point> queue{{INIT}}, seen{queue}, next;
while (queue.size() != 0 && (part2 || !seen.count(TARGET)) && (!part2 || steps != LIMIT)) {
for (const auto& q : queue)
for (const auto& d : DIRS)
if (valid(q + d) && !seen.count(q + d))
next.emplace(q + d), seen.emplace(q + d);
next.swap(queue), next.clear(), ++steps;
}
os << (part2 ? seen.size() : steps) << std::endl;
}