148 lines
3.6 KiB
C++
148 lines
3.6 KiB
C++
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
#include <aoc/WarehouseWoes.hpp>
|
|
|
|
#include <sstream>
|
|
|
|
WarehouseWoes::WarehouseWoes(const int inputFileNameSuffix)
|
|
: LinesSolver{ inputFileNameSuffix }, isProcessingMap_{ true }, isSearchingStartPosition_{ true }, lines2_{},
|
|
warehouseBoxPusher1_{ getBoxChar(), getWallChar(), getEmptyChar() },
|
|
warehouseBoxPusher2_{ getLeftWideBoxChar(), getRightWideBoxChar(), getWallChar(), getEmptyChar() }
|
|
{
|
|
}
|
|
|
|
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_)
|
|
{
|
|
checkStartingPosition(line);
|
|
LinesSolver::processDataLine(line);
|
|
addWarehouseMap2Line(line);
|
|
}
|
|
else
|
|
{
|
|
warehouseBoxPusher1_.processMovements(lines, line);
|
|
warehouseBoxPusher2_.processMovements(lines2_, line);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isProcessingMap_ = false;
|
|
}
|
|
}
|
|
|
|
void WarehouseWoes::finish()
|
|
{
|
|
part1 = calcAllGpsCoordinates(lines, getBoxChar());
|
|
part2 = calcAllGpsCoordinates(lines2_, getLeftWideBoxChar());
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getRobotChar()
|
|
{
|
|
return '@';
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getBoxChar()
|
|
{
|
|
return 'O';
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getLeftWideBoxChar()
|
|
{
|
|
return '[';
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getRightWideBoxChar()
|
|
{
|
|
return ']';
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getWallChar()
|
|
{
|
|
return '#';
|
|
}
|
|
|
|
constexpr char WarehouseWoes::getEmptyChar()
|
|
{
|
|
return '.';
|
|
}
|
|
|
|
void WarehouseWoes::checkStartingPosition(const std::string& line)
|
|
{
|
|
if (isSearchingStartPosition_)
|
|
{
|
|
auto hit = line.find(getRobotChar());
|
|
if (hit != std::string::npos)
|
|
{
|
|
int x = static_cast<int>(hit);
|
|
int y = static_cast<int>(lines.size());
|
|
warehouseBoxPusher1_.setRobotPosition({ x, y });
|
|
warehouseBoxPusher2_.setRobotPosition({ x * 2, y });
|
|
isSearchingStartPosition_ = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WarehouseWoes::addWarehouseMap2Line(const std::string& line)
|
|
{
|
|
std::ostringstream stream{};
|
|
for (const char c : line)
|
|
{
|
|
if (c == getBoxChar())
|
|
{
|
|
stream << getLeftWideBoxChar() << getRightWideBoxChar();
|
|
}
|
|
else
|
|
{
|
|
stream << c << c;
|
|
}
|
|
}
|
|
lines2_.push_back(stream.str());
|
|
}
|
|
|
|
long long int WarehouseWoes::calcAllGpsCoordinates(Lines& warehouseMap, const char boxChar)
|
|
{
|
|
long long int result{ 0 };
|
|
for (size_t j = 0; j < warehouseMap.size(); j++)
|
|
{
|
|
for (size_t i = 0; i < warehouseMap[j].size(); i++)
|
|
{
|
|
if (warehouseMap[j][i] == boxChar)
|
|
{
|
|
result += calcGpsCoordinate(i, j);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
long long int WarehouseWoes::calcGpsCoordinate(const size_t x, const size_t y)
|
|
{
|
|
return x + 100 * y;
|
|
}
|