Add solution for "Day 6: Guard Gallivant", part 1

This commit is contained in:
Stefan Müller 2024-12-06 23:31:38 +01:00
parent cf19ba7b61
commit a6ed7bb65b
9 changed files with 158 additions and 6 deletions

View File

@ -130,6 +130,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="AdventOfCode2024.cpp" /> <ClCompile Include="AdventOfCode2024.cpp" />
<ClCompile Include="CeresSearch.cpp" /> <ClCompile Include="CeresSearch.cpp" />
<ClCompile Include="GuardGallivant.cpp" />
<ClCompile Include="HistorianHysteria.cpp" /> <ClCompile Include="HistorianHysteria.cpp" />
<ClCompile Include="LinesSolver.cpp" /> <ClCompile Include="LinesSolver.cpp" />
<ClCompile Include="MullDataState.cpp" /> <ClCompile Include="MullDataState.cpp" />
@ -152,6 +153,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="CeresSearch.h" /> <ClInclude Include="CeresSearch.h" />
<ClInclude Include="GuardGallivant.h" />
<ClInclude Include="HistorianHysteria.h" /> <ClInclude Include="HistorianHysteria.h" />
<ClInclude Include="LinesSolver.h" /> <ClInclude Include="LinesSolver.h" />
<ClInclude Include="MullDataState.h" /> <ClInclude Include="MullDataState.h" />

View File

@ -78,6 +78,9 @@
<ClCompile Include="PrintQueue.cpp"> <ClCompile Include="PrintQueue.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GuardGallivant.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="SolverEngine.h"> <ClInclude Include="SolverEngine.h">
@ -146,5 +149,8 @@
<ClInclude Include="PrintQueue.h"> <ClInclude Include="PrintQueue.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GuardGallivant.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,91 @@
// 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 "GuardGallivant.h"
std::string GuardGallivant::getPuzzleName() const
{
return "Day 6: Guard Gallivant";
}
std::string GuardGallivant::getInputFileName() const
{
return "guard_gallivant.txt";
}
void GuardGallivant::processDataLine(const std::string& line)
{
LinesSolver::processDataLine(line);
auto pos{ line.find(getStartChar()) };
if (pos != std::string::npos)
{
start_ = Point2{ static_cast<int>(pos), static_cast<int>(lines.size() - 1) };
}
}
void GuardGallivant::finish()
{
auto dirIndex{ getStartDirectionIndex() };
auto current{ start_ };
visitPosition(current);
auto next{ current + Point2::cardinalDirections[dirIndex] };
while (isInBounds(next))
{
if (getPosition(next) == getObstructionChar())
{
dirIndex = turnDirection(dirIndex);
}
else
{
current = next;
visitPosition(current);
}
next = current + Point2::cardinalDirections[dirIndex];
}
}
void GuardGallivant::visitPosition(const Point2& current)
{
if (getPosition(current) != getVisitedChar())
{
setPosition(current, getVisitedChar());
part1++;
}
}
size_t GuardGallivant::turnDirection(const size_t current) const
{
return current == 0 ? 3 : current - 1;
}
size_t GuardGallivant::getStartDirectionIndex() const
{
return 2;
}
char GuardGallivant::getStartChar() const
{
return '^';
}
char GuardGallivant::getVisitedChar() const
{
return 'X';
}
char GuardGallivant::getObstructionChar() const
{
return '#';
}

View File

@ -0,0 +1,35 @@
// 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 "LinesSolver.h"
class GuardGallivant :
public LinesSolver
{
public:
Point2 start_{};
std::string getPuzzleName() const override;
std::string getInputFileName() const override;
void processDataLine(const std::string& line) override;
void finish() override;
void visitPosition(const Point2& current);
size_t turnDirection(const size_t current) const;
size_t getStartDirectionIndex() const;
char getStartChar() const;
char getVisitedChar() const;
char getObstructionChar() const;
};

View File

@ -20,13 +20,18 @@ void LinesSolver::processDataLine(const std::string& line)
lines.push_back(line); lines.push_back(line);
} }
bool LinesSolver::isInBounds(const Point2& point) bool LinesSolver::isInBounds(const Point2& point) const
{ {
return 0 <= point.y && point.y < lines.size() return 0 <= point.y && point.y < lines.size()
&& 0 <= point.x && point.x < lines[point.y].size(); && 0 <= point.x && point.x < lines[point.y].size();
} }
char LinesSolver::getPosition(const Point2& point) char LinesSolver::getPosition(const Point2& point) const
{ {
return lines[point.y][point.x]; return lines[point.y][point.x];
} }
void LinesSolver::setPosition(const Point2& point, const char value)
{
lines[point.y][point.x] = value;
}

View File

@ -27,6 +27,7 @@ class LinesSolver :
void processDataLine(const std::string& line) override; void processDataLine(const std::string& line) override;
protected: protected:
std::vector<std::string> lines{}; std::vector<std::string> lines{};
bool isInBounds(const Point2& point); bool isInBounds(const Point2& point) const;
char getPosition(const Point2& point); char getPosition(const Point2& point) const;
void setPosition(const Point2& point, const char value);
}; };

View File

@ -23,8 +23,10 @@ const Point2 Point2::upLeft{ -1, -1 };
const Point2 Point2::upRight{ 1, -1 }; const Point2 Point2::upRight{ 1, -1 };
const Point2 Point2::downLeft{ -1, 1 }; const Point2 Point2::downLeft{ -1, 1 };
const Point2 Point2::downRight{ 1, 1 }; const Point2 Point2::downRight{ 1, 1 };
const Point2 Point2::directions[] = { Point2::left, Point2::right, Point2::up, Point2::down, const Point2 Point2::directions[] = { Point2::down, Point2::downRight, Point2::right,
Point2::upLeft, Point2::upRight, Point2::downLeft, Point2::downRight }; Point2::upRight, Point2::up, Point2::upLeft, Point2::left, Point2::downLeft };
const Point2 Point2::cardinalDirections[] = { Point2::down, Point2::right, Point2::up,
Point2::left};
Point2::Point2() Point2::Point2()
: Point2{ 0, 0 } {} : Point2{ 0, 0 } {}

View File

@ -20,7 +20,15 @@ class Point2
public: public:
static const Point2 left, right, up, down; static const Point2 left, right, up, down;
static const Point2 upLeft, upRight, downLeft, downRight; static const Point2 upLeft, upRight, downLeft, downRight;
/// <summary>
/// The eight cardinal and diagonal directions starting down, rotating in
/// positive direction.
/// </summary>
static const Point2 directions[8]; static const Point2 directions[8];
/// <summary>
/// The four cardinal directions starting down, rotating in positive direction.
/// </summary>
static const Point2 cardinalDirections[4];
int x, y; int x, y;
Point2(); Point2();
Point2(const int x, const int y); Point2(const int x, const int y);

View File

@ -25,6 +25,7 @@
#include "MullItOver.h" #include "MullItOver.h"
#include "CeresSearch.h" #include "CeresSearch.h"
#include "PrintQueue.h" #include "PrintQueue.h"
#include "GuardGallivant.h"
void Program::run() void Program::run()
{ {
@ -40,6 +41,7 @@ void Program::runSolvers()
solverEngine.run(*std::make_unique<MullItOver>()); solverEngine.run(*std::make_unique<MullItOver>());
solverEngine.run(*std::make_unique<CeresSearch>()); solverEngine.run(*std::make_unique<CeresSearch>());
solverEngine.run(*std::make_unique<PrintQueue>()); solverEngine.run(*std::make_unique<PrintQueue>());
solverEngine.run(*std::make_unique<GuardGallivant>());
} }
std::vector<std::string> Program::getInputPaths() const std::vector<std::string> Program::getInputPaths() const