Add solution for "Day 13: Claw Contraption", part 2
This commit is contained in:
parent
e6a132521b
commit
973f62163d
|
@ -84,6 +84,12 @@ The perimeter of a region is the sum of neighbors for all plots encountered duri
|
|||
|
||||
Adding up the products of area and perimeter, or area and corner count, per region gives us the solution.
|
||||
|
||||
### Day 13: Claw Contraption
|
||||
|
||||
:mag_right: Puzzle: <https://adventofcode.com/2024/day/13>, :white_check_mark: Solver: [`ClawContraption.cpp`](src/ClawContraption.cpp)
|
||||
|
||||
For each claw machine, we have to solve a simple linear equation system to get the number of required button pushes. Conveniently, for the given data, all of these systems have a unique solution. However, some solutions have to be excluded because the number of button pushes is not integer, or because the solutions are too high for part 1. The required integer tests are done by performing integer division, and comparing the dividend with the product of the integer quotient and the divisor.
|
||||
|
||||
## Thanks
|
||||
|
||||
* [Alexander Brouwer](https://github.com/Bromvlieg) for getting the project set up with CMake.
|
||||
|
|
|
@ -31,5 +31,7 @@ class ClawContraption : public Solver
|
|||
static constexpr int getNMaxButtonPushes();
|
||||
static constexpr int getButtonACost();
|
||||
static constexpr int getButtonBCost();
|
||||
long long int calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize);
|
||||
static constexpr long long int getConversionCorrection();
|
||||
long long int calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize,
|
||||
const long long int offset);
|
||||
};
|
||||
|
|
|
@ -60,7 +60,8 @@ void ClawContraption::processDataLine(const std::string& line)
|
|||
stream >> x;
|
||||
std::getline(stream, token, '=');
|
||||
stream >> y;
|
||||
part1 += calcTokenCost(buttonA_, buttonB_, { x, y });
|
||||
part1 += calcTokenCost(buttonA_, buttonB_, { x, y }, 0);
|
||||
part2 += calcTokenCost(buttonA_, buttonB_, { x, y }, getConversionCorrection());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,17 +85,24 @@ constexpr int ClawContraption::getButtonBCost()
|
|||
return 1;
|
||||
}
|
||||
|
||||
long long int ClawContraption::calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize)
|
||||
constexpr long long int ClawContraption::getConversionCorrection()
|
||||
{
|
||||
long long int p{ prize.y * buttonB.x - prize.x * buttonB.y };
|
||||
return 10000000000000;
|
||||
}
|
||||
|
||||
long long int ClawContraption::calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize,
|
||||
const long long int offset)
|
||||
{
|
||||
long long int p{ (prize.y + offset) * buttonB.x - (prize.x + offset) * buttonB.y };
|
||||
long long int q{ buttonA.y * buttonB.x - buttonA.x * buttonB.y };
|
||||
long long int a{ p / q };
|
||||
if (a * q != p || a > getNMaxButtonPushes())
|
||||
if (a * q != p || (offset == 0 && a > getNMaxButtonPushes()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
long long int b{ (prize.x - a * buttonA.x) / buttonB.x };
|
||||
if (b > getNMaxButtonPushes())
|
||||
long long int r{ prize.x + offset - a * buttonA.x };
|
||||
long long int b{ r / buttonB.x };
|
||||
if (b * buttonB.x != r || (offset == 0 && b > getNMaxButtonPushes()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -212,11 +212,11 @@ TEST_CASE("[ClawContraptionTests]")
|
|||
TestContext test;
|
||||
SECTION("FullData")
|
||||
{
|
||||
test.run(std::make_unique<ClawContraption>(), 36571, 0, test.getInputPaths());
|
||||
test.run(std::make_unique<ClawContraption>(), 36571, 85527711500010, test.getInputPaths());
|
||||
}
|
||||
SECTION("ExampleData")
|
||||
{
|
||||
test.run(std::make_unique<ClawContraption>(), 480, 0, test.getExampleInputPaths());
|
||||
test.run(std::make_unique<ClawContraption>(), 480, 875318608908, test.getExampleInputPaths());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue