diff --git a/AdventOfCode2024/AdventOfCode2024.vcxproj b/AdventOfCode2024/AdventOfCode2024.vcxproj index 8b36b05..35bfe34 100644 --- a/AdventOfCode2024/AdventOfCode2024.vcxproj +++ b/AdventOfCode2024/AdventOfCode2024.vcxproj @@ -130,6 +130,7 @@ + @@ -152,6 +153,7 @@ + diff --git a/AdventOfCode2024/AdventOfCode2024.vcxproj.filters b/AdventOfCode2024/AdventOfCode2024.vcxproj.filters index 5ebe69f..feac5aa 100644 --- a/AdventOfCode2024/AdventOfCode2024.vcxproj.filters +++ b/AdventOfCode2024/AdventOfCode2024.vcxproj.filters @@ -78,6 +78,9 @@ Source Files + + Source Files + @@ -146,5 +149,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/AdventOfCode2024/GuardGallivant.cpp b/AdventOfCode2024/GuardGallivant.cpp new file mode 100644 index 0000000..55b3f9c --- /dev/null +++ b/AdventOfCode2024/GuardGallivant.cpp @@ -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 . + +#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(pos), static_cast(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 '#'; +} diff --git a/AdventOfCode2024/GuardGallivant.h b/AdventOfCode2024/GuardGallivant.h new file mode 100644 index 0000000..160f4dc --- /dev/null +++ b/AdventOfCode2024/GuardGallivant.h @@ -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 . + +#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; +}; diff --git a/AdventOfCode2024/LinesSolver.cpp b/AdventOfCode2024/LinesSolver.cpp index f6b68ee..4664b2c 100644 --- a/AdventOfCode2024/LinesSolver.cpp +++ b/AdventOfCode2024/LinesSolver.cpp @@ -20,13 +20,18 @@ void LinesSolver::processDataLine(const std::string& 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() && 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]; } + +void LinesSolver::setPosition(const Point2& point, const char value) +{ + lines[point.y][point.x] = value; +} diff --git a/AdventOfCode2024/LinesSolver.h b/AdventOfCode2024/LinesSolver.h index 9a2d8bb..b58ed7c 100644 --- a/AdventOfCode2024/LinesSolver.h +++ b/AdventOfCode2024/LinesSolver.h @@ -27,6 +27,7 @@ class LinesSolver : void processDataLine(const std::string& line) override; protected: std::vector lines{}; - bool isInBounds(const Point2& point); - char getPosition(const Point2& point); + bool isInBounds(const Point2& point) const; + char getPosition(const Point2& point) const; + void setPosition(const Point2& point, const char value); }; diff --git a/AdventOfCode2024/Point2.cpp b/AdventOfCode2024/Point2.cpp index 7252aee..e632533 100644 --- a/AdventOfCode2024/Point2.cpp +++ b/AdventOfCode2024/Point2.cpp @@ -23,8 +23,10 @@ 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 }; +const Point2 Point2::directions[] = { Point2::down, Point2::downRight, Point2::right, + 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{ 0, 0 } {} diff --git a/AdventOfCode2024/Point2.h b/AdventOfCode2024/Point2.h index 29dc176..45e06c4 100644 --- a/AdventOfCode2024/Point2.h +++ b/AdventOfCode2024/Point2.h @@ -20,7 +20,15 @@ class Point2 public: static const Point2 left, right, up, down; static const Point2 upLeft, upRight, downLeft, downRight; + /// + /// The eight cardinal and diagonal directions starting down, rotating in + /// positive direction. + /// static const Point2 directions[8]; + /// + /// The four cardinal directions starting down, rotating in positive direction. + /// + static const Point2 cardinalDirections[4]; int x, y; Point2(); Point2(const int x, const int y); diff --git a/AdventOfCode2024/Program.cpp b/AdventOfCode2024/Program.cpp index c800644..d0abe52 100644 --- a/AdventOfCode2024/Program.cpp +++ b/AdventOfCode2024/Program.cpp @@ -25,6 +25,7 @@ #include "MullItOver.h" #include "CeresSearch.h" #include "PrintQueue.h" +#include "GuardGallivant.h" void Program::run() { @@ -40,6 +41,7 @@ void Program::runSolvers() solverEngine.run(*std::make_unique()); solverEngine.run(*std::make_unique()); solverEngine.run(*std::make_unique()); + solverEngine.run(*std::make_unique()); } std::vector Program::getInputPaths() const