diff --git a/include/aoc/ClawContraption.hpp b/include/aoc/ClawContraption.hpp
new file mode 100644
index 0000000..5835ba9
--- /dev/null
+++ b/include/aoc/ClawContraption.hpp
@@ -0,0 +1,35 @@
+// Solutions to the Advent Of Code 2024.
+// Copyright (C) 2025 Stefan Müller
+//
+// This program is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your option) any later
+// version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program. If not, see .
+
+#pragma once
+
+#include
+#include
+
+class ClawContraption : public Solver
+{
+public:
+ virtual const std::string getPuzzleName() const override;
+ virtual const int getPuzzleDay() const override;
+ virtual void processDataLine(const std::string& line) override;
+ virtual void finish() override;
+private:
+ Point2 buttonA_;
+ Point2 buttonB_;
+ 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);
+};
diff --git a/src/ClawContraption.cpp b/src/ClawContraption.cpp
new file mode 100644
index 0000000..9b2a713
--- /dev/null
+++ b/src/ClawContraption.cpp
@@ -0,0 +1,102 @@
+// Solutions to the Advent Of Code 2024.
+// Copyright (C) 2025 Stefan Müller
+//
+// This program is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your option) any later
+// version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program. If not, see .
+
+#include
+
+#include
+
+const std::string ClawContraption::getPuzzleName() const
+{
+ return "Claw Contraption";
+}
+
+const int ClawContraption::getPuzzleDay() const
+{
+ return 13;
+}
+
+void ClawContraption::processDataLine(const std::string& line)
+{
+ if (!line.empty())
+ {
+ std::istringstream stream{ line };
+ std::string token;
+ char c;
+ int x;
+ int y;
+
+ stream >> token;
+ if (token == "Button")
+ {
+ stream >> c;
+ std::getline(stream, token, '+');
+ stream >> x;
+ std::getline(stream, token, '+');
+ stream >> y;
+ if (c == 'A')
+ {
+ buttonA_ = { x, y };
+ }
+ else
+ {
+ buttonB_ = { x, y };
+ }
+ }
+ else
+ {
+ std::getline(stream, token, '=');
+ stream >> x;
+ std::getline(stream, token, '=');
+ stream >> y;
+ part1 += calcTokenCost(buttonA_, buttonB_, { x, y });
+ }
+ }
+}
+
+void ClawContraption::finish()
+{
+}
+
+constexpr int ClawContraption::getNMaxButtonPushes()
+{
+ return 100;
+}
+
+constexpr int ClawContraption::getButtonACost()
+{
+ return 3;
+}
+
+constexpr int ClawContraption::getButtonBCost()
+{
+ return 1;
+}
+
+long long int ClawContraption::calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize)
+{
+ long long int p{ prize.y * buttonB.x - prize.x * 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())
+ {
+ return 0;
+ }
+ long long int b{ (prize.x - a * buttonA.x) / buttonB.x };
+ if (b > getNMaxButtonPushes())
+ {
+ return 0;
+ }
+ return a * getButtonACost() + b * getButtonBCost();
+}
diff --git a/src/Program.cpp b/src/Program.cpp
index 9e20db1..6cef544 100644
--- a/src/Program.cpp
+++ b/src/Program.cpp
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
void Program::run()
@@ -63,6 +64,7 @@ void Program::runSolvers()
runSolver(solverEngine);
runSolver(solverEngine);
runSolver(solverEngine);
+ runSolver(solverEngine);
runSolver(solverEngine);
}
diff --git a/tests/src/TestCases.cpp b/tests/src/TestCases.cpp
index e2afe14..680c526 100644
--- a/tests/src/TestCases.cpp
+++ b/tests/src/TestCases.cpp
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#define REQUIRE_MESSAGE(cond, msg) if (!(cond)) { INFO(msg); REQUIRE(cond); }
@@ -206,6 +207,19 @@ TEST_CASE("[GardenGroupsTests]")
}
}
+TEST_CASE("[ClawContraptionTests]")
+{
+ TestContext test;
+ SECTION("FullData")
+ {
+ test.run(std::make_unique(), 36571, 0, test.getInputPaths());
+ }
+ SECTION("ExampleData")
+ {
+ test.run(std::make_unique(), 480, 0, test.getExampleInputPaths());
+ }
+}
+
TEST_CASE("[LanPartyTests]")
{
TestContext test;