Line data Source code
1 : #include "PuzzleImpl.h"
2 :
3 : #include "Regex.h"
4 : #include "Vector.h"
5 :
6 : #include <numeric>
7 :
8 : namespace {
9 :
10 : struct ClawMachine {
11 : Vec2<int64_t> a;
12 : Vec2<int64_t> b;
13 : Vec2<int64_t> p;
14 : };
15 :
16 2 : std::vector<ClawMachine> parse(std::string_view const input, Vec2<int64_t> add = {0, 0}) {
17 2 : std::vector<ClawMachine> result;
18 2 : std::string regex =
19 2 : R"(Button A\: X\+(\d+), Y\+(\d+)\nButton B\: X\+(\d+), Y\+(\d+)\nPrize\: X=(\d+), Y=(\d+))";
20 2 : FindAndConsume<int64_t, int64_t, int64_t, int64_t, int64_t, int64_t> consume(regex);
21 640 : for (auto [ax, ay, bx, by, px, py] : consume(input)) {
22 640 : result.emplace_back(Vec2<int64_t>{ax, ay}, Vec2<int64_t>{bx, by}, Vec2<int64_t>{px, py} + add);
23 640 : }
24 2 : return result;
25 2 : }
26 :
27 640 : size_t solve(ClawMachine const &machine) {
28 640 : Vec2<double> const a{machine.a};
29 640 : Vec2<double> const b{machine.b};
30 640 : Vec2<double> const p{machine.p};
31 :
32 640 : Vec2<double> const n =
33 640 : Vec2<double>{b.y() * p.x() - b.x() * p.y(), a.x() * p.y() - a.y() * p.x()} /
34 640 : (a.x() * b.y() - a.y() * b.x());
35 :
36 640 : Vec2<int64_t> in{static_cast<int64_t>(std::round(n.x())),
37 640 : static_cast<int64_t>(std::round(n.y()))};
38 :
39 640 : if (in.x() * machine.a + in.y() * machine.b == machine.p)
40 320 : return in.x() * 3 + in.y();
41 320 : else
42 320 : return 0;
43 640 : }
44 :
45 : } // namespace
46 :
47 1 : template <> size_t part1<2024, 13>(std::string_view const input) {
48 1 : auto machines = parse(input);
49 1 : return std::transform_reduce(machines.begin(), machines.end(), size_t(0), std::plus{}, solve);
50 1 : }
51 :
52 1 : template <> size_t part2<2024, 13>(std::string_view const input) {
53 1 : auto machines = parse(input, Vec2<int64_t>(10000000000000, 10000000000000));
54 1 : return std::transform_reduce(machines.begin(), machines.end(), size_t(0), std::plus{}, solve);
55 1 : }
|