From 02af288ebc4a7f71456d1454c34f87663a978d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Tue, 4 Mar 2025 12:06:16 +0100 Subject: [PATCH] Add solution for "Day 15: Warehouse Woes", part 1 --- include/aoc/Point2.hpp | 1 + include/aoc/WarehouseWoes.hpp | 38 ++++++++++++ src/Point2.cpp | 18 ++++++ src/Program.cpp | 2 + src/WarehouseWoes.cpp | 114 ++++++++++++++++++++++++++++++++++ tests/src/TestCases.cpp | 18 ++++++ 6 files changed, 191 insertions(+) create mode 100644 include/aoc/WarehouseWoes.hpp create mode 100644 src/WarehouseWoes.cpp diff --git a/include/aoc/Point2.hpp b/include/aoc/Point2.hpp index 82cc65d..9bdade1 100644 --- a/include/aoc/Point2.hpp +++ b/include/aoc/Point2.hpp @@ -31,6 +31,7 @@ class Point2 /// The four cardinal directions starting down, rotating in positive direction. /// static const std::array cardinalDirections; + static Point2 getCardinalDirection(const char directionChar); int x, y; Point2(); Point2(const int x, const int y); diff --git a/include/aoc/WarehouseWoes.hpp b/include/aoc/WarehouseWoes.hpp new file mode 100644 index 0000000..10c36d1 --- /dev/null +++ b/include/aoc/WarehouseWoes.hpp @@ -0,0 +1,38 @@ +// 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 + +class WarehouseWoes + : public LinesSolver +{ +public: + WarehouseWoes(const int inputFileNameSuffix = 0); + 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: + bool isProcessingMap_; + Point2 robotPosition_; + static constexpr char getRobotChar(); + static constexpr char getBoxChar(); + static constexpr char getWallChar(); + static constexpr char getEmptyChar(); + void processDirections(const std::string& line); + int calcGpsCoordinate(const size_t x, const size_t y); +}; diff --git a/src/Point2.cpp b/src/Point2.cpp index 004289f..9469644 100644 --- a/src/Point2.cpp +++ b/src/Point2.cpp @@ -27,6 +27,24 @@ const std::array Point2::directions = { Point2::down, Point2::downRig Point2::up, Point2::upLeft, Point2::left, Point2::downLeft }; const std::array Point2::cardinalDirections = { Point2::down, Point2::right, Point2::up, Point2::left }; +Point2 Point2::getCardinalDirection(const char directionChar) +{ + switch (directionChar) + { + case 'v' : + return Point2::down; + case '>' : + return Point2::right; + case '^' : + return Point2::up; + case '<' : + return Point2::left; + default : + return { 0, 0 }; + } +} + + Point2::Point2() : Point2{ 0, 0 } { diff --git a/src/Program.cpp b/src/Program.cpp index 5c84d14..f88ac2d 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include void Program::run() @@ -67,6 +68,7 @@ void Program::runSolvers() runSolver(solverEngine); runSolver(solverEngine); runSolver(solverEngine); + runSolver(solverEngine); runSolver(solverEngine); } diff --git a/src/WarehouseWoes.cpp b/src/WarehouseWoes.cpp new file mode 100644 index 0000000..deb4dc7 --- /dev/null +++ b/src/WarehouseWoes.cpp @@ -0,0 +1,114 @@ +// 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 + +WarehouseWoes::WarehouseWoes(const int inputFileNameSuffix) + : LinesSolver{ inputFileNameSuffix }, isProcessingMap_{ true }, robotPosition_{} +{ +} + +const std::string WarehouseWoes::getPuzzleName() const +{ + return "Warehouse Woes"; +} + +const int WarehouseWoes::getPuzzleDay() const +{ + return 15; +} + +void WarehouseWoes::processDataLine(const std::string& line) +{ + if (!line.empty()) + { + if (isProcessingMap_) + { + auto hit = line.find(getRobotChar()); + if (hit != std::string::npos) + { + robotPosition_ = { static_cast(hit), static_cast(lines.size()) }; + } + LinesSolver::processDataLine(line); + } + else + { + processDirections(line); + } + } + else + { + isProcessingMap_ = false; + } +} + +void WarehouseWoes::finish() +{ + for (size_t j = 0; j < lines.size(); j++) + { + for (size_t i = 0; i < lines[j].size(); i++) + { + if (lines[j][i] == getBoxChar()) + { + part1 += calcGpsCoordinate(i, j); + } + } + } +} + +constexpr char WarehouseWoes::getRobotChar() +{ + return '@'; +} + +constexpr char WarehouseWoes::getBoxChar() +{ + return 'O'; +} + +constexpr char WarehouseWoes::getWallChar() +{ + return '#'; +} + +constexpr char WarehouseWoes::getEmptyChar() +{ + return '.'; +} + +void WarehouseWoes::processDirections(const std::string& line) +{ + for (const char c : line) + { + const Point2 direction{ Point2::getCardinalDirection(c) }; + const Point2 next{ robotPosition_ + direction }; + Point2 push{ next }; + while (getCharAt(push) == getBoxChar()) + { + push += direction; + } + if (getCharAt(push) != getWallChar()) + { + setCharAt(push, getBoxChar()); + setCharAt(next, getEmptyChar()); + robotPosition_ = next; + } + } +} + +int WarehouseWoes::calcGpsCoordinate(const size_t x, const size_t y) +{ + return x + 100 * y; +} diff --git a/tests/src/TestCases.cpp b/tests/src/TestCases.cpp index d333bb5..9fd78cc 100644 --- a/tests/src/TestCases.cpp +++ b/tests/src/TestCases.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #define REQUIRE_MESSAGE(cond, msg) if (!(cond)) { INFO(msg); REQUIRE(cond); } @@ -234,6 +235,23 @@ TEST_CASE("[RestroomRedoubtTests]") } } +TEST_CASE("[WarehouseWoesTests]") +{ + TestContext test; + SECTION("FullData") + { + test.run(std::make_unique(), 1515788, 0, test.getInputPaths()); + } + SECTION("ExampleData") + { + test.run(std::make_unique(), 10092, 0, test.getExampleInputPaths()); + } + SECTION("ExampleData2") + { + test.run(std::make_unique(2), 2028, 0, test.getExampleInputPaths()); + } +} + TEST_CASE("[LanPartyTests]") { TestContext test;