Add solutions for "Day 4: Ceres Search"
This commit is contained in:
parent
08ddddacff
commit
4f049c06d8
|
@ -129,7 +129,9 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="AdventOfCode2024.cpp" />
|
<ClCompile Include="AdventOfCode2024.cpp" />
|
||||||
|
<ClCompile Include="CeresSearch.cpp" />
|
||||||
<ClCompile Include="HistorianHysteria.cpp" />
|
<ClCompile Include="HistorianHysteria.cpp" />
|
||||||
|
<ClCompile Include="LinesSolver.cpp" />
|
||||||
<ClCompile Include="MullDataState.cpp" />
|
<ClCompile Include="MullDataState.cpp" />
|
||||||
<ClCompile Include="MullToggleCloseState.cpp" />
|
<ClCompile Include="MullToggleCloseState.cpp" />
|
||||||
<ClCompile Include="MullDoOpenState.cpp" />
|
<ClCompile Include="MullDoOpenState.cpp" />
|
||||||
|
@ -139,6 +141,7 @@
|
||||||
<ClCompile Include="MullItOver.cpp" />
|
<ClCompile Include="MullItOver.cpp" />
|
||||||
<ClCompile Include="MullStates.cpp" />
|
<ClCompile Include="MullStates.cpp" />
|
||||||
<ClCompile Include="MullCharState.cpp" />
|
<ClCompile Include="MullCharState.cpp" />
|
||||||
|
<ClCompile Include="Point2.cpp" />
|
||||||
<ClCompile Include="Program.cpp" />
|
<ClCompile Include="Program.cpp" />
|
||||||
<ClCompile Include="RedNosedReports.cpp" />
|
<ClCompile Include="RedNosedReports.cpp" />
|
||||||
<ClCompile Include="Solver.cpp" />
|
<ClCompile Include="Solver.cpp" />
|
||||||
|
@ -147,7 +150,9 @@
|
||||||
<ClCompile Include="StringStateMachine.cpp" />
|
<ClCompile Include="StringStateMachine.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="CeresSearch.h" />
|
||||||
<ClInclude Include="HistorianHysteria.h" />
|
<ClInclude Include="HistorianHysteria.h" />
|
||||||
|
<ClInclude Include="LinesSolver.h" />
|
||||||
<ClInclude Include="MullDataState.h" />
|
<ClInclude Include="MullDataState.h" />
|
||||||
<ClInclude Include="MullToggleCloseState.h" />
|
<ClInclude Include="MullToggleCloseState.h" />
|
||||||
<ClInclude Include="MullDoOpenState.h" />
|
<ClInclude Include="MullDoOpenState.h" />
|
||||||
|
@ -157,6 +162,7 @@
|
||||||
<ClInclude Include="MullItOver.h" />
|
<ClInclude Include="MullItOver.h" />
|
||||||
<ClInclude Include="MullStates.h" />
|
<ClInclude Include="MullStates.h" />
|
||||||
<ClInclude Include="MullCharState.h" />
|
<ClInclude Include="MullCharState.h" />
|
||||||
|
<ClInclude Include="Point2.h" />
|
||||||
<ClInclude Include="Program.h" />
|
<ClInclude Include="Program.h" />
|
||||||
<ClInclude Include="RedNosedReportData.h" />
|
<ClInclude Include="RedNosedReportData.h" />
|
||||||
<ClInclude Include="RedNosedReports.h" />
|
<ClInclude Include="RedNosedReports.h" />
|
||||||
|
|
|
@ -66,6 +66,15 @@
|
||||||
<ClCompile Include="MullStates.cpp">
|
<ClCompile Include="MullStates.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Point2.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CeresSearch.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LinesSolver.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="SolverEngine.h">
|
<ClInclude Include="SolverEngine.h">
|
||||||
|
@ -122,5 +131,14 @@
|
||||||
<ClInclude Include="MullDataState.h">
|
<ClInclude Include="MullDataState.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Point2.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="CeresSearch.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="LinesSolver.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "CeresSearch.h"
|
||||||
|
|
||||||
|
std::string CeresSearch::getPuzzleName() const
|
||||||
|
{
|
||||||
|
return "Day 4: Ceres Search";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CeresSearch::getInputFileName() const
|
||||||
|
{
|
||||||
|
return "ceres_search.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CeresSearch::finish()
|
||||||
|
{
|
||||||
|
for (int j = 0; j < lines.size(); j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lines[j].size(); i++)
|
||||||
|
{
|
||||||
|
if (lines[j][i] == xmas[0])
|
||||||
|
{
|
||||||
|
Point2 start{ i, j };
|
||||||
|
computeXmasCount(start);
|
||||||
|
}
|
||||||
|
else if (lines[j][i] == xmas[2])
|
||||||
|
{
|
||||||
|
Point2 start{ i, j };
|
||||||
|
computeX_MasCount(start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CeresSearch::computeXmasCount(const Point2& start)
|
||||||
|
{
|
||||||
|
for (auto d : Point2::directions)
|
||||||
|
{
|
||||||
|
auto p{ start + d };
|
||||||
|
auto i{ 1 };
|
||||||
|
while (i < 4 && isInBounds(p) && xmas[i] == getPosition(p))
|
||||||
|
{
|
||||||
|
p += d;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == 4)
|
||||||
|
{
|
||||||
|
part1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CeresSearch::computeX_MasCount(const Point2& start)
|
||||||
|
{
|
||||||
|
auto pUL{ start + Point2::upLeft };
|
||||||
|
auto pDR{ start + Point2::downRight };
|
||||||
|
auto pUR{ start + Point2::upRight };
|
||||||
|
auto pDL{ start + Point2::downLeft };
|
||||||
|
if (isInBounds(pUL) && isInBounds(pDR)
|
||||||
|
&& ((getPosition(pUL) == xmas[1] && getPosition(pDR) == xmas[3])
|
||||||
|
|| (getPosition(pUL) == xmas[3] && getPosition(pDR) == xmas[1]))
|
||||||
|
&& ((getPosition(pUR) == xmas[1] && getPosition(pDL) == xmas[3])
|
||||||
|
|| (getPosition(pUR) == xmas[3] && getPosition(pDL) == xmas[1])))
|
||||||
|
{
|
||||||
|
part2++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "LinesSolver.h"
|
||||||
|
|
||||||
|
class CeresSearch :
|
||||||
|
public LinesSolver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string getPuzzleName() const override;
|
||||||
|
std::string getInputFileName() const override;
|
||||||
|
void finish() override;
|
||||||
|
private:
|
||||||
|
char xmas[4] = { 'X', 'M', 'A', 'S' };
|
||||||
|
void computeXmasCount(const Point2& start);
|
||||||
|
void computeX_MasCount(const Point2& start);
|
||||||
|
};
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "LinesSolver.h"
|
||||||
|
|
||||||
|
void LinesSolver::processDataLine(const std::string& line)
|
||||||
|
{
|
||||||
|
lines.push_back(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinesSolver::isInBounds(const Point2& point)
|
||||||
|
{
|
||||||
|
return 0 <= point.y && point.y < lines.size()
|
||||||
|
&& 0 <= point.x && point.x < lines[point.y].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
char LinesSolver::getPosition(const Point2& point)
|
||||||
|
{
|
||||||
|
return lines[point.y][point.x];
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Solver.h"
|
||||||
|
#include "Point2.h"
|
||||||
|
|
||||||
|
class LinesSolver :
|
||||||
|
public Solver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void processDataLine(const std::string& line) override;
|
||||||
|
protected:
|
||||||
|
std::vector<std::string> lines{};
|
||||||
|
bool isInBounds(const Point2& point);
|
||||||
|
char getPosition(const Point2& point);
|
||||||
|
};
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "Point2.h"
|
||||||
|
|
||||||
|
Point2::Point2()
|
||||||
|
: Point2{ 0, 0 } {}
|
||||||
|
|
||||||
|
Point2::Point2(const int x, const int y)
|
||||||
|
: x{ x }, y{ y } {}
|
||||||
|
|
||||||
|
bool Point2::operator==(const Point2& rhs) const
|
||||||
|
{
|
||||||
|
return x == rhs.x && y == rhs.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Point2::operator!=(const Point2& rhs) const
|
||||||
|
{
|
||||||
|
return !(x == y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2 Point2::operator+(const Point2& rhs) const
|
||||||
|
{
|
||||||
|
return Point2(x + rhs.x, y + rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2 Point2::operator-(const Point2& rhs) const
|
||||||
|
{
|
||||||
|
return Point2(x - rhs.x, y - rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2 Point2::operator*(const int rhs) const
|
||||||
|
{
|
||||||
|
return Point2(x * rhs, y * rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2 Point2::operator-() const
|
||||||
|
{
|
||||||
|
return Point2(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2& Point2::operator+=(const Point2& rhs)
|
||||||
|
{
|
||||||
|
*this = *this + rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2& Point2::operator-=(const Point2& rhs)
|
||||||
|
{
|
||||||
|
*this = *this - rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2& Point2::operator*=(const int rhs)
|
||||||
|
{
|
||||||
|
*this = *this * rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Point2 Point2::left{ -1, 0 };
|
||||||
|
const Point2 Point2::right{ 1, 0 };
|
||||||
|
const Point2 Point2::up{ 0, -1 };
|
||||||
|
const Point2 Point2::down{ 0, 1 };
|
||||||
|
const Point2 Point2::upLeft{ -1, -1 };
|
||||||
|
const Point2 Point2::upRight{ 1, -1 };
|
||||||
|
const Point2 Point2::downLeft{ -1, 1 };
|
||||||
|
const Point2 Point2::downRight{ 1, 1 };
|
||||||
|
const Point2 Point2::directions[] = { Point2::left, Point2::right, Point2::up, Point2::down,
|
||||||
|
Point2::upLeft, Point2::upRight, Point2::downLeft, Point2::downRight };
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Solutions to the Advent Of Code 2024.
|
||||||
|
// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Point2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int x, y;
|
||||||
|
Point2();
|
||||||
|
Point2(const int x, const int y);
|
||||||
|
bool operator==(const Point2& rhs) const;
|
||||||
|
bool operator!=(const Point2& rhs) const;
|
||||||
|
Point2 operator+(const Point2& rhs) const;
|
||||||
|
Point2 operator-(const Point2& rhs) const;
|
||||||
|
Point2 operator*(const int rhs) const;
|
||||||
|
Point2 operator-() const;
|
||||||
|
Point2& operator+=(const Point2& rhs);
|
||||||
|
Point2& operator-=(const Point2& rhs);
|
||||||
|
Point2& operator*=(const int rhs);
|
||||||
|
static const Point2 left, right, up, down;
|
||||||
|
static const Point2 upLeft, upRight, downLeft, downRight;
|
||||||
|
static const Point2 directions[8];
|
||||||
|
};
|
|
@ -23,6 +23,7 @@
|
||||||
#include "HistorianHysteria.h"
|
#include "HistorianHysteria.h"
|
||||||
#include "RedNosedReports.h"
|
#include "RedNosedReports.h"
|
||||||
#include "MullItOver.h"
|
#include "MullItOver.h"
|
||||||
|
#include "CeresSearch.h"
|
||||||
|
|
||||||
void Program::run()
|
void Program::run()
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,7 @@ void Program::runSolvers()
|
||||||
solverEngine.run(*std::make_unique<HistorianHysteria>());
|
solverEngine.run(*std::make_unique<HistorianHysteria>());
|
||||||
solverEngine.run(*std::make_unique<RedNosedReports>());
|
solverEngine.run(*std::make_unique<RedNosedReports>());
|
||||||
solverEngine.run(*std::make_unique<MullItOver>());
|
solverEngine.run(*std::make_unique<MullItOver>());
|
||||||
|
solverEngine.run(*std::make_unique<CeresSearch>());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> Program::getInputPaths() const
|
std::vector<std::string> Program::getInputPaths() const
|
||||||
|
|
|
@ -101,8 +101,8 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;..\$(Platform)\$(Configuration);D:\Projects\VS\AdventOfCode2024Full\code\AdventOfCode2024\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>Solver.obj;SolverEngine.obj;HistorianHysteria.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Solver.obj;SolverEngine.obj;HistorianHysteria.obj;RedNosedReports.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
|
|
@ -32,6 +32,12 @@ Here, we have a few conditionals to determine on the fly which of the numbers wo
|
||||||
|
|
||||||
A simple [finite state machine](AdventOfCode2024/StringStateMachine.h) crawling along the input character by character solves both parts nicely. The algorithm tracks whether `mul` instructions are enabled or not, but ignores this setting for part 1.
|
A simple [finite state machine](AdventOfCode2024/StringStateMachine.h) crawling along the input character by character solves both parts nicely. The algorithm tracks whether `mul` instructions are enabled or not, but ignores this setting for part 1.
|
||||||
|
|
||||||
|
### Day 4: Ceres Search
|
||||||
|
|
||||||
|
:mag_right: Puzzle: <https://adventofcode.com/2024/day/4>, :white_check_mark: Solver: [`CeresSearch.cpp`](AdventOfCode2024/CeresSearch.cpp)
|
||||||
|
|
||||||
|
For this puzzle I added a class for [points in two-dimensional space](AdventOfCode2024/Point2.h), so I can use these for simplifying directional computations. With that, the algorithm looks for all `X` and `A` for part 1 and 2, respectively, and tries to find the remaining characters, starting from that `X` or `A`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (C) 2024 Stefan Müller
|
Copyright (C) 2024 Stefan Müller
|
||||||
|
|
Loading…
Reference in New Issue