-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchallenge13.cpp
More file actions
112 lines (87 loc) · 3.29 KB
/
challenge13.cpp
File metadata and controls
112 lines (87 loc) · 3.29 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "challenge13.hpp"
#include "helper.hpp"
#include "print.hpp"
#include "3rdParty/ctre/include/ctre.hpp"
#include <algorithm>
#include <ranges>
namespace {
struct Equation {
std::int64_t AFactor;
std::int64_t BFactor;
std::int64_t Result;
Equation& operator-=(const Equation& that) noexcept {
AFactor -= that.AFactor;
BFactor -= that.BFactor;
Result -= that.Result;
return *this;
}
Equation operator-(const Equation& that) const noexcept {
auto ret{*this};
return ret -= that;
}
Equation& operator/=(std::int64_t divider) noexcept {
AFactor /= divider;
BFactor /= divider;
Result /= divider;
return *this;
}
friend Equation operator*(std::int64_t factor, Equation eq) noexcept {
eq.AFactor *= factor;
eq.BFactor *= factor;
eq.Result *= factor;
return eq;
}
};
struct ClawMachine {
Equation A;
Equation B;
std::int64_t costOfWinning(void) const noexcept {
auto b = A.AFactor * B - B.AFactor * A;
if ( b.Result % b.BFactor != 0 ) {
return 0;
} //if ( b.Result % b.BFactor != 0 )
b /= b.BFactor;
auto a = A - A.BFactor * b;
if ( a.Result % a.AFactor != 0 ) {
return 0;
} //if ( a.Result % a.AFactor != 0 )
a /= a.AFactor;
return 3 * a.Result + b.Result;
}
void bumpForPart2(void) noexcept {
A.Result += 10'000'000'000'000;
B.Result += 10'000'000'000'000;
return;
}
};
auto parse(const std::vector<std::string_view>& input) {
auto buttonRegEx = ctre::match<R"(Button .: X\+(\d+), Y\+(\d+))">;
auto prizeRegEx = ctre::match<R"(Prize: X=(\d+), Y=(\d+))">;
std::vector<ClawMachine> ret;
for ( auto machineInput : input | std::views::chunk(4) ) {
throwIfInvalid(std::ranges::distance(machineInput) >= 3);
auto iter = std::ranges::begin(machineInput);
auto aMatch = buttonRegEx(*iter);
auto bMatch = buttonRegEx(*++iter);
auto prizeMatch = prizeRegEx(*++iter);
throwIfInvalid(aMatch && bMatch && prizeMatch);
auto matchesToEquation = [&]<std::size_t I>(void) noexcept {
return Equation{convert(aMatch.get<I>().view()), convert(bMatch.get<I>().view()),
convert(prizeMatch.get<I>().view())};
};
ret.push_back(ClawMachine{matchesToEquation.operator()<1>(), matchesToEquation.operator()<2>()});
} //for ( auto inputLine : input )
return ret;
}
} //namespace
bool challenge13(const std::vector<std::string_view>& input) {
auto clawMachines = parse(input);
const auto sum1 =
std::ranges::fold_left(clawMachines | std::views::transform(&ClawMachine::costOfWinning), 0, std::plus<>{});
myPrint(" == Result of Part 1: {:d} ==\n", sum1);
std::ranges::for_each(clawMachines, &ClawMachine::bumpForPart2);
const auto sum2 =
std::ranges::fold_left(clawMachines | std::views::transform(&ClawMachine::costOfWinning), 0, std::plus<>{});
myPrint(" == Result of Part 2: {:d} ==\n", sum2);
return sum1 == 37901 && sum2 == 77'407'675'412'647;
}