diff --git a/include/aoc/RaceCondition.hpp b/include/aoc/RaceCondition.hpp
new file mode 100644
index 0000000..cca4cd2
--- /dev/null
+++ b/include/aoc/RaceCondition.hpp
@@ -0,0 +1,37 @@
+// 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 RaceCondition
+ : public LinesSolver
+{
+public:
+ RaceCondition(const int threshold = 100);
+ virtual const std::string getPuzzleName() const override;
+ virtual const int getPuzzleDay() const override;
+ virtual void finish() override;
+private:
+ static constexpr char getStartChar();
+ static constexpr char getWallChar();
+ static constexpr int getCheatLength();
+ const std::array doubleSteps_{ Point2::down * 2, Point2::downRight, Point2::right * 2,
+ Point2::upRight, Point2::up * 2, Point2::upLeft, Point2::left * 2, Point2::downLeft };
+ int threshold_;
+ void checkCheat(const Point2& position, Grid& times);
+};
diff --git a/src/Program.cpp b/src/Program.cpp
index 0284db3..79e8586 100644
--- a/src/Program.cpp
+++ b/src/Program.cpp
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
void Program::run()
@@ -77,6 +78,7 @@ void Program::runSolvers()
runSolver(solverEngine);
runSolver(solverEngine);
runSolver(solverEngine);
+ runSolver(solverEngine);
runSolver(solverEngine);
}
diff --git a/src/RaceCondition.cpp b/src/RaceCondition.cpp
new file mode 100644
index 0000000..dcb26cd
--- /dev/null
+++ b/src/RaceCondition.cpp
@@ -0,0 +1,91 @@
+// 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
+
+RaceCondition::RaceCondition(const int threshold)
+ : threshold_{ threshold }
+{
+}
+
+const std::string RaceCondition::getPuzzleName() const
+{
+ return "Race Condition";
+}
+
+const int RaceCondition::getPuzzleDay() const
+{
+ return 20;
+}
+
+void RaceCondition::finish()
+{
+ int time{ 0 };
+ Grid times{ lines.size(), lines[0].size() };
+ // Fills the grid with a number that is guaranteed to be greater than the length of the path.
+ times.fill(static_cast(times.getNColumns() * times.getNRows()));
+
+ Point2 position{ findChar(getStartChar()) };
+ Point2 previous{ -1, -1 };
+ while (position != previous)
+ {
+ // Tracks time for current position.
+ times.cell(position) = time++;
+
+ // Checks if there is a cheat leading to the current position.
+ checkCheat(position, times);
+
+ // Progresses the race path.
+ auto oldPosition = position;
+ for (const auto& direction : Point2::cardinalDirections)
+ {
+ auto next = position + direction;
+ if (next != previous && getCharAt(next) != getWallChar())
+ {
+ position = next;
+ break;
+ }
+ }
+ previous = oldPosition;
+ }
+}
+
+constexpr char RaceCondition::getStartChar()
+{
+ return 'S';
+}
+
+constexpr char RaceCondition::getWallChar()
+{
+ return '#';
+}
+
+constexpr int RaceCondition::getCheatLength()
+{
+ return 2;
+}
+
+void RaceCondition::checkCheat(const Point2& position, Grid& times)
+{
+ auto time = times.cell(position);
+ for (auto& direction : doubleSteps_)
+ {
+ auto other = position + direction;
+ if (isInBounds(other) && time >= threshold_ + times.cell(other) + getCheatLength())
+ {
+ part1++;
+ }
+ }
+}
diff --git a/tests/src/TestCases.cpp b/tests/src/TestCases.cpp
index 4ac4211..322d5ed 100644
--- a/tests/src/TestCases.cpp
+++ b/tests/src/TestCases.cpp
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#define REQUIRE_MESSAGE(cond, msg) if (!(cond)) { INFO(msg); REQUIRE(cond); }
@@ -354,6 +355,19 @@ TEST_CASE("[LinenLayoutTests]")
}
}
+TEST_CASE("[RaceConditionTests]")
+{
+ TestContext test;
+ SECTION("FullData")
+ {
+ test.runFull(std::make_unique(), 1448, 0);
+ }
+ SECTION("ExampleData")
+ {
+ test.runExample(std::make_unique(2), 44, 0);
+ }
+}
+
TEST_CASE("[LanPartyTests]")
{
TestContext test;