Merge branch 'cmake'
This commit is contained in:
80
src/CeresSearch.cpp
Normal file
80
src/CeresSearch.cpp
Normal file
@@ -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 <aoc/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++;
|
||||
}
|
||||
}
|
||||
91
src/GuardGallivant.cpp
Normal file
91
src/GuardGallivant.cpp
Normal 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 <aoc/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 '#';
|
||||
}
|
||||
70
src/HistorianHysteria.cpp
Normal file
70
src/HistorianHysteria.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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 <iostream>
|
||||
|
||||
#include <aoc/HistorianHysteria.h>
|
||||
|
||||
std::string HistorianHysteria::getPuzzleName() const
|
||||
{
|
||||
return "Day 1: Historian Hysteria";
|
||||
}
|
||||
|
||||
std::string HistorianHysteria::getInputFileName() const
|
||||
{
|
||||
return "historian_hysteria.txt";
|
||||
}
|
||||
|
||||
void HistorianHysteria::processDataLine(const std::string& line)
|
||||
{
|
||||
auto pos{ line.find(" ") };
|
||||
left.insert(std::stoi(line.substr(0, pos)));
|
||||
right.insert(std::stoi(line.substr(pos + 3)));
|
||||
}
|
||||
|
||||
void HistorianHysteria::finish()
|
||||
{
|
||||
int prev{ 0 };
|
||||
auto nSame{ 0 };
|
||||
auto leftIterator{ left.begin() };
|
||||
auto rightIterator{ right.begin() };
|
||||
auto rightSameIterator{ right.begin() };
|
||||
|
||||
while (leftIterator != left.end())
|
||||
{
|
||||
part1 += abs(*leftIterator - *rightIterator);
|
||||
|
||||
if (prev != *leftIterator)
|
||||
{
|
||||
nSame = 0;
|
||||
// Skips over numbers in the right list that are smaller than the current left number.
|
||||
while (rightSameIterator != right.end() && *rightSameIterator < *leftIterator)
|
||||
{
|
||||
rightSameIterator++;
|
||||
}
|
||||
// Counts the occurrences of the current left number in the right list.
|
||||
while (rightSameIterator != right.end() && *rightSameIterator == *leftIterator)
|
||||
{
|
||||
rightSameIterator++;
|
||||
nSame++;
|
||||
}
|
||||
prev = *leftIterator;
|
||||
}
|
||||
part2 += *leftIterator * nSame;
|
||||
|
||||
leftIterator++;
|
||||
rightIterator++;
|
||||
}
|
||||
}
|
||||
37
src/LinesSolver.cpp
Normal file
37
src/LinesSolver.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 <aoc/LinesSolver.h>
|
||||
|
||||
void LinesSolver::processDataLine(const std::string& line)
|
||||
{
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
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) const
|
||||
{
|
||||
return lines[point.y][point.x];
|
||||
}
|
||||
|
||||
void LinesSolver::setPosition(const Point2& point, const char value)
|
||||
{
|
||||
lines[point.y][point.x] = value;
|
||||
}
|
||||
37
src/MullCharState.cpp
Normal file
37
src/MullCharState.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 <aoc/MullCharState.h>
|
||||
|
||||
MullCharState::MullCharState(const char expected)
|
||||
: expected_{ expected }, successState_{}, failState_{} {}
|
||||
|
||||
void MullCharState::next(StringStateMachine* stateMachine)
|
||||
{
|
||||
if (stateMachine->getCurrent() == expected_)
|
||||
{
|
||||
stateMachine->setState(*successState_);
|
||||
}
|
||||
else
|
||||
{
|
||||
stateMachine->setState(*failState_);
|
||||
}
|
||||
}
|
||||
|
||||
void MullCharState::setTransitions(StringState& successState, StringState& failState)
|
||||
{
|
||||
successState_ = &successState;
|
||||
failState_ = &failState;
|
||||
}
|
||||
66
src/MullData.cpp
Normal file
66
src/MullData.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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 <aoc/MullData.h>
|
||||
|
||||
MullData::MullData()
|
||||
: isEnabled_{ true }, factor1_{ 0 }, factor2_{ 0 }, part1_{ 0 }, part2_{ 0 } {};
|
||||
|
||||
bool MullData::getIsEnabled()
|
||||
{
|
||||
return isEnabled_;
|
||||
}
|
||||
|
||||
void MullData::setIsEnabled(const bool value)
|
||||
{
|
||||
isEnabled_ = value;
|
||||
}
|
||||
|
||||
int MullData::getFactor(const int index)
|
||||
{
|
||||
return index == 1 ? factor1_ : factor2_;
|
||||
}
|
||||
|
||||
void MullData::setFactor(const int index, const int value)
|
||||
{
|
||||
if (index == 1)
|
||||
{
|
||||
factor1_ = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
factor2_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
void MullData::updateResult()
|
||||
{
|
||||
auto product = factor1_ * factor2_;
|
||||
part1_ += product;
|
||||
if (isEnabled_)
|
||||
{
|
||||
part2_ += product;
|
||||
}
|
||||
}
|
||||
|
||||
long long int MullData::getResultPart1()
|
||||
{
|
||||
return part1_;
|
||||
}
|
||||
|
||||
long long int MullData::getResultPart2()
|
||||
{
|
||||
return part2_;
|
||||
}
|
||||
21
src/MullDataState.cpp
Normal file
21
src/MullDataState.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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 <aoc/MullDataState.h>
|
||||
|
||||
void MullDataState::setData(MullData& data)
|
||||
{
|
||||
data_ = &data;
|
||||
}
|
||||
39
src/MullDoOpenState.cpp
Normal file
39
src/MullDoOpenState.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 <aoc/MullDoOpenState.h>
|
||||
|
||||
void MullDoOpenState::next(StringStateMachine* stateMachine)
|
||||
{
|
||||
if (stateMachine->getCurrent() == '(' && !data_->getIsEnabled())
|
||||
{
|
||||
stateMachine->setState(*doState_);
|
||||
}
|
||||
else if (stateMachine->getCurrent() == 'n' && data_->getIsEnabled())
|
||||
{
|
||||
stateMachine->setState(*dontState_);
|
||||
}
|
||||
else
|
||||
{
|
||||
stateMachine->setState(*failState_);
|
||||
}
|
||||
}
|
||||
|
||||
void MullDoOpenState::setTransitions(StringState& doState, StringState& dontState, StringState& failState)
|
||||
{
|
||||
doState_ = &doState;
|
||||
dontState_ = &dontState;
|
||||
failState_ = &failState;
|
||||
}
|
||||
39
src/MullEntryState.cpp
Normal file
39
src/MullEntryState.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 <aoc/MullEntryState.h>
|
||||
|
||||
void MullEntryState::enter(StringStateMachine* stateMachine)
|
||||
{
|
||||
next(stateMachine);
|
||||
}
|
||||
|
||||
void MullEntryState::next(StringStateMachine* stateMachine)
|
||||
{
|
||||
if (stateMachine->getCurrent() == 'm')
|
||||
{
|
||||
stateMachine->setState(*mulState_);
|
||||
}
|
||||
else if (stateMachine->getCurrent() == 'd')
|
||||
{
|
||||
stateMachine->setState(*doState_);
|
||||
}
|
||||
}
|
||||
|
||||
void MullEntryState::setTransitions(StringState& mulState, StringState& doState)
|
||||
{
|
||||
mulState_ = &mulState;
|
||||
doState_ = &doState;
|
||||
}
|
||||
58
src/MullFactorState.cpp
Normal file
58
src/MullFactorState.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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 <aoc/MullFactorState.h>
|
||||
|
||||
MullFactorState::MullFactorState(const char expected, const int index)
|
||||
: expected_{ expected }, index_{ index }, successState_{}, failState_{} {}
|
||||
|
||||
void MullFactorState::enter(StringStateMachine* stateMachine)
|
||||
{
|
||||
data_->setFactor(index_, 0);
|
||||
}
|
||||
|
||||
void MullFactorState::next(StringStateMachine* stateMachine)
|
||||
{
|
||||
if (stateMachine->getCurrent() == expected_ && data_->getFactor(index_) > 0)
|
||||
{
|
||||
if (index_ == 2)
|
||||
{
|
||||
data_->updateResult();
|
||||
}
|
||||
stateMachine->setState(*successState_);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = stateMachine->getCurrent() - '0';
|
||||
if (0 <= x && x <= 9)
|
||||
{
|
||||
data_->setFactor(index_, data_->getFactor(index_) * 10 + x);
|
||||
if (data_->getFactor(index_) > 999)
|
||||
{
|
||||
stateMachine->setState(*failState_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stateMachine->setState(*failState_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MullFactorState::setTransitions(StringState& successState, StringState& failState)
|
||||
{
|
||||
successState_ = &successState;
|
||||
failState_ = &failState;
|
||||
}
|
||||
44
src/MullItOver.cpp
Normal file
44
src/MullItOver.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 <aoc/MullItOver.h>
|
||||
#include <aoc/StringStateMachine.h>
|
||||
|
||||
MullItOver::MullItOver()
|
||||
: Solver{}, data_{}, states_ {
|
||||
data_
|
||||
} {}
|
||||
|
||||
std::string MullItOver::getPuzzleName() const
|
||||
{
|
||||
return "Day 3: Mull It Over";
|
||||
}
|
||||
|
||||
std::string MullItOver::getInputFileName() const
|
||||
{
|
||||
return "mull_it_over.txt";
|
||||
}
|
||||
|
||||
void MullItOver::processDataLine(const std::string& line)
|
||||
{
|
||||
StringStateMachine stateMachine{ line, states_.entryState };
|
||||
stateMachine.run();
|
||||
}
|
||||
|
||||
void MullItOver::finish()
|
||||
{
|
||||
part1 = data_.getResultPart1();
|
||||
part2 = data_.getResultPart2();
|
||||
}
|
||||
38
src/MullStates.cpp
Normal file
38
src/MullStates.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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 <aoc/MullStates.h>
|
||||
|
||||
MullStates::MullStates(MullData& data)
|
||||
{
|
||||
entryState.setTransitions(uState, oState);
|
||||
uState.setTransitions(lState, entryState);
|
||||
lState.setTransitions(mulOpenState, entryState);
|
||||
mulOpenState.setTransitions(factor1State, entryState);
|
||||
factor1State.setData(data);
|
||||
factor1State.setTransitions(factor2State, entryState);
|
||||
factor2State.setData(data);
|
||||
factor2State.setTransitions(entryState, entryState);
|
||||
oState.setTransitions(doOpenState, entryState);
|
||||
doOpenState.setData(data);
|
||||
doOpenState.setTransitions(doCloseState, apostropheState, entryState);
|
||||
doCloseState.setData(data);
|
||||
doCloseState.setTransitions(entryState);
|
||||
apostropheState.setTransitions(tState, entryState);
|
||||
tState.setTransitions(dontOpenState, entryState);
|
||||
dontOpenState.setTransitions(dontCloseState, entryState);
|
||||
dontCloseState.setData(data);
|
||||
dontCloseState.setTransitions(entryState);
|
||||
}
|
||||
33
src/MullToggleCloseState.cpp
Normal file
33
src/MullToggleCloseState.cpp
Normal file
@@ -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/>.
|
||||
|
||||
#include <aoc/MullToggleCloseState.h>
|
||||
|
||||
MullToggleCloseState::MullToggleCloseState(const bool isEnabler)
|
||||
: isEnabler_{ isEnabler }, successState_{} {}
|
||||
|
||||
void MullToggleCloseState::next(StringStateMachine* stateMachine)
|
||||
{
|
||||
if (stateMachine->getCurrent() == ')')
|
||||
{
|
||||
data_->setIsEnabled(isEnabler_);
|
||||
}
|
||||
stateMachine->setState(*successState_);
|
||||
}
|
||||
|
||||
void MullToggleCloseState::setTransitions(StringState& successState)
|
||||
{
|
||||
successState_ = &successState;
|
||||
}
|
||||
83
src/Point2.cpp
Normal file
83
src/Point2.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// 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 <aoc/Point2.h>
|
||||
|
||||
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::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 } {}
|
||||
|
||||
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;
|
||||
}
|
||||
120
src/PrintQueue.cpp
Normal file
120
src/PrintQueue.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
// 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 <algorithm>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <aoc/PrintQueue.h>
|
||||
|
||||
PrintQueue::PrintQueue()
|
||||
: Solver{}, pageNoMapIndex_{ 0 }, isProcessingOrderingRules_{ true }, orderingRules_{}
|
||||
{
|
||||
for (size_t i = 0; i <= maxPageNo_; i++)
|
||||
{
|
||||
pageNoMap_[i] = -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nPages_; i++)
|
||||
{
|
||||
for (size_t j = 0; j < nPages_; j++)
|
||||
{
|
||||
orderingRules_[i][j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string PrintQueue::getPuzzleName() const
|
||||
{
|
||||
return "Day 5: Print Queue";
|
||||
}
|
||||
|
||||
std::string PrintQueue::getInputFileName() const
|
||||
{
|
||||
return "print_queue.txt";
|
||||
}
|
||||
|
||||
void PrintQueue::processDataLine(const std::string& line)
|
||||
{
|
||||
if (isProcessingOrderingRules_)
|
||||
{
|
||||
if (line.empty())
|
||||
{
|
||||
isProcessingOrderingRules_ = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
processOrderingRule(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
processUpdatePages(line);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintQueue::finish()
|
||||
{
|
||||
}
|
||||
|
||||
size_t PrintQueue::getMapped(const int pageNo)
|
||||
{
|
||||
if (pageNoMap_[pageNo] < 0)
|
||||
{
|
||||
pageNoMap_[pageNo] = pageNoMapIndex_++;
|
||||
}
|
||||
return pageNoMap_[pageNo];
|
||||
}
|
||||
|
||||
void PrintQueue::processOrderingRule(const std::string& line)
|
||||
{
|
||||
auto pos{ line.find("|") };
|
||||
auto before{ std::stoi(line.substr(0, pos)) };
|
||||
auto after{ std::stoi(line.substr(pos + 1)) };
|
||||
orderingRules_[getMapped(before)][getMapped(after)] = true;
|
||||
}
|
||||
|
||||
void PrintQueue::processUpdatePages(const std::string& line)
|
||||
{
|
||||
std::vector<size_t> pages{};
|
||||
std::stringstream stream{ line };
|
||||
std::string token;
|
||||
auto isCorrectOrder{ true };
|
||||
// We completely construct 'pages' for part 2, even if the ordering is not correct.
|
||||
while (std::getline(stream, token, ','))
|
||||
{
|
||||
size_t page = std::stoi(token);
|
||||
size_t i{ 0 };
|
||||
while (isCorrectOrder && i < pages.size())
|
||||
{
|
||||
isCorrectOrder = !orderingRules_[getMapped(page)][getMapped(pages[i])];
|
||||
i++;
|
||||
}
|
||||
pages.push_back(page);
|
||||
}
|
||||
|
||||
if (isCorrectOrder)
|
||||
{
|
||||
part1 += pages[pages.size() / 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// This works because the input defines a complete ordering on the occurring
|
||||
// page numbers.
|
||||
std::sort(pages.begin(), pages.end(),
|
||||
[&](int const& a, int const& b) { return orderingRules_[getMapped(a)][getMapped(b)]; });
|
||||
part2 += pages[pages.size() / 2];
|
||||
}
|
||||
}
|
||||
50
src/Program.cpp
Normal file
50
src/Program.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <aoc/Program.h>
|
||||
#include <aoc/SolverEngine.h>
|
||||
|
||||
// Solver implementations in day order.
|
||||
#include <aoc/HistorianHysteria.h>
|
||||
#include <aoc/RedNosedReports.h>
|
||||
#include <aoc/MullItOver.h>
|
||||
#include <aoc/CeresSearch.h>
|
||||
#include <aoc/PrintQueue.h>
|
||||
#include <aoc/GuardGallivant.h>
|
||||
|
||||
void Program::run()
|
||||
{
|
||||
std::cout << "### Advent of Code 2024 ###\n";
|
||||
runSolvers();
|
||||
}
|
||||
|
||||
void Program::runSolvers()
|
||||
{
|
||||
SolverEngine solverEngine{ getInputPaths() };
|
||||
solverEngine.run(*std::make_unique<HistorianHysteria>());
|
||||
solverEngine.run(*std::make_unique<RedNosedReports>());
|
||||
solverEngine.run(*std::make_unique<MullItOver>());
|
||||
solverEngine.run(*std::make_unique<CeresSearch>());
|
||||
solverEngine.run(*std::make_unique<PrintQueue>());
|
||||
solverEngine.run(*std::make_unique<GuardGallivant>());
|
||||
}
|
||||
|
||||
std::vector<std::string> Program::getInputPaths() const
|
||||
{
|
||||
return std::vector<std::string>{ "data", "../../../data", "../../../../data" };
|
||||
}
|
||||
176
src/RedNosedReports.cpp
Normal file
176
src/RedNosedReports.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// 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 <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <aoc/RedNosedReports.h>
|
||||
|
||||
std::string RedNosedReports::getPuzzleName() const
|
||||
{
|
||||
return "Day 2: Red-Nosed Reports";
|
||||
}
|
||||
|
||||
std::string RedNosedReports::getInputFileName() const
|
||||
{
|
||||
return "red-nosed_reports.txt";
|
||||
}
|
||||
|
||||
// 'X' in the comments here and below marks the level that must be ignored to
|
||||
// make the report safe.
|
||||
// 'first' means that this series starts at the beginning of the line.
|
||||
// 'next' means that the level(s) from the next loop iteration(s) will determine
|
||||
// which level to ignore.
|
||||
void RedNosedReports::processDataLine(const std::string& line)
|
||||
{
|
||||
RedNosedReportData data{};
|
||||
|
||||
std::stringstream stream{ line };
|
||||
std::string token;
|
||||
std::getline(stream, token, ' ');
|
||||
data.levels.push_back(std::stoi(token));
|
||||
|
||||
while (data.isSafe && std::getline(stream, token, ' '))
|
||||
{
|
||||
do
|
||||
{
|
||||
data.levels.push_back(std::stoi(token));
|
||||
} while (data.mustAwaitFourLevels && data.levels.size() < 4
|
||||
&& std::getline(stream, token, ' '));
|
||||
|
||||
if (data.mustCheckSlopeReversal)
|
||||
{
|
||||
auto it = data.levels.rbegin();
|
||||
if (data.slope == Slope::Decreasing && *it > *(++it))
|
||||
{
|
||||
// X
|
||||
// first 3 2 6 7
|
||||
data.slope = Slope::Increasing;
|
||||
}
|
||||
else if (data.slope == Slope::Increasing && *it < *(++it))
|
||||
{
|
||||
// X
|
||||
// first 6 7 3 2
|
||||
data.slope = Slope::Decreasing;
|
||||
}
|
||||
else
|
||||
{
|
||||
// X
|
||||
// first 3 2 6 1
|
||||
// first 6 7 3 8
|
||||
data.mustSkipPrevious = true;
|
||||
}
|
||||
}
|
||||
data.mustCheckSlopeReversal = false;
|
||||
|
||||
auto it = data.levels.rbegin();
|
||||
auto delta{ *it };
|
||||
delta -= *(++(data.mustSkipPrevious ? ++it : it));
|
||||
data.mustSkipPrevious = false;
|
||||
|
||||
if (delta == 0)
|
||||
{
|
||||
// X
|
||||
// 1 1
|
||||
data.isSafe = data.canUseDampener;
|
||||
data.canUseDampener = false;
|
||||
}
|
||||
else if (delta > 0)
|
||||
{
|
||||
checkLastLevel(Slope::Increasing, Slope::Decreasing, delta, 1, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLastLevel(Slope::Decreasing, Slope::Increasing, -delta, -1, data);
|
||||
}
|
||||
}
|
||||
if (data.isSafe)
|
||||
{
|
||||
if (data.canUseDampener)
|
||||
{
|
||||
part1++;
|
||||
}
|
||||
part2++;
|
||||
}
|
||||
}
|
||||
|
||||
void RedNosedReports::finish()
|
||||
{
|
||||
}
|
||||
|
||||
void RedNosedReports::checkLastLevel(const Slope sameSlope, const Slope otherSlope,
|
||||
const int delta, const int sign, RedNosedReportData& data)
|
||||
{
|
||||
if (data.slope == sameSlope)
|
||||
{
|
||||
if (delta > 3)
|
||||
{
|
||||
// X X
|
||||
// 1 2 6 8 7 3
|
||||
data.mustSkipPrevious = true;
|
||||
data.isSafe = data.canUseDampener;
|
||||
data.canUseDampener = false;
|
||||
}
|
||||
}
|
||||
else if (data.slope == otherSlope)
|
||||
{
|
||||
if (data.levels.size() == 3 && sign * (data.levels[2] - data.levels[0]) <= 3)
|
||||
{
|
||||
// X X next X X next
|
||||
// first 3 2 6 ??? first 6 7 3 ???
|
||||
data.mustCheckSlopeReversal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// X X
|
||||
// first 3 2 7 first 6 7 2
|
||||
// 3 2 1 4 6 7 8 5
|
||||
data.mustSkipPrevious = true;
|
||||
}
|
||||
data.isSafe = data.canUseDampener;
|
||||
data.canUseDampener = false;
|
||||
}
|
||||
else // slope == Slope::Unknown
|
||||
{
|
||||
if (delta <= 3)
|
||||
{
|
||||
data.slope = sameSlope;
|
||||
}
|
||||
if (data.mustAwaitFourLevels)
|
||||
{
|
||||
if (delta <= 3
|
||||
&& ((0 < sign * (data.levels[2] - data.levels[0]) && sign * (data.levels[2] - data.levels[0]) <= 3)
|
||||
|| (0 < sign * (data.levels[2] - data.levels[1]) && sign * (data.levels[2] - data.levels[1]) <= 3)))
|
||||
{
|
||||
// X X X X
|
||||
// first 1 5 3 4 first 8 4 6 5
|
||||
data.mustAwaitFourLevels = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.isSafe = false;
|
||||
}
|
||||
}
|
||||
else if (delta > 3)
|
||||
{
|
||||
// X X next X X next
|
||||
// first 1 5 ??? first 8 4 ???
|
||||
data.mustAwaitFourLevels = true;
|
||||
data.isSafe = data.canUseDampener;
|
||||
data.canUseDampener = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/Solver.cpp
Normal file
29
src/Solver.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 <aoc/Solver.h>
|
||||
|
||||
Solver::Solver()
|
||||
: part1{ 0 }, part2{ 0 } {}
|
||||
|
||||
long long int Solver::getResultPart1() const
|
||||
{
|
||||
return part1;
|
||||
}
|
||||
|
||||
long long int Solver::getResultPart2() const
|
||||
{
|
||||
return part2;
|
||||
}
|
||||
76
src/SolverEngine.cpp
Normal file
76
src/SolverEngine.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// 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 <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <aoc/SolverEngine.h>
|
||||
|
||||
SolverEngine::SolverEngine(const std::vector<std::string>& inputPaths)
|
||||
: inputPaths_{ inputPaths } {}
|
||||
|
||||
void SolverEngine::run(Solver& solver)
|
||||
{
|
||||
std::cout << "\n--- " << solver.getPuzzleName() << " ---\n";
|
||||
|
||||
auto fullFilePath = tryGetValidFullInputFilePath(solver.getInputFileName());
|
||||
if (fullFilePath != "")
|
||||
{
|
||||
std::string line;
|
||||
std::ifstream inputFile{ fullFilePath };
|
||||
while (std::getline(inputFile, line))
|
||||
{
|
||||
solver.processDataLine(line);
|
||||
}
|
||||
inputFile.close();
|
||||
|
||||
solver.finish();
|
||||
|
||||
std::cout << "Part 1: " << solver.getResultPart1()
|
||||
<< "\nPart 2: " << solver.getResultPart2() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::path SolverEngine::tryGetValidFullInputFilePath(const std::string& inputFileName)
|
||||
{
|
||||
for (auto path : inputPaths_)
|
||||
{
|
||||
std::filesystem::path fullFilePath = path;
|
||||
fullFilePath /= inputFileName;
|
||||
if (std::filesystem::exists(fullFilePath))
|
||||
{
|
||||
return fullFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Cannot find puzzle input file '";
|
||||
for (size_t i = 0; i < inputPaths_.size(); i++)
|
||||
{
|
||||
std::filesystem::path fullFilePath = inputPaths_[i];
|
||||
fullFilePath /= inputFileName;
|
||||
std::cout << std::filesystem::absolute(fullFilePath).string();
|
||||
if (i + 2 < inputPaths_.size())
|
||||
{
|
||||
std::cout << "', '";
|
||||
}
|
||||
else if (i + 1 < inputPaths_.size())
|
||||
{
|
||||
std::cout << "', or '";
|
||||
}
|
||||
}
|
||||
std::cout << "'. Please download the file content from https://adventofcode.com/2024/\n";
|
||||
|
||||
return "";
|
||||
}
|
||||
46
src/StringStateMachine.cpp
Normal file
46
src/StringStateMachine.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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 <aoc/StringStateMachine.h>
|
||||
|
||||
StringStateMachine::StringStateMachine(const std::string& line, StringState& entryState)
|
||||
{
|
||||
line_ = line;
|
||||
entryState_ = &entryState;
|
||||
currentState_ = entryState_;
|
||||
current_ = ' ';
|
||||
}
|
||||
|
||||
void StringStateMachine::run()
|
||||
{
|
||||
currentState_ = entryState_;
|
||||
for (auto c : line_)
|
||||
{
|
||||
current_ = c;
|
||||
currentState_->next(this);
|
||||
}
|
||||
}
|
||||
|
||||
char StringStateMachine::getCurrent() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
|
||||
void StringStateMachine::setState(StringState& state)
|
||||
{
|
||||
currentState_->exit(this);
|
||||
currentState_ = &state;
|
||||
currentState_->enter(this);
|
||||
}
|
||||
Reference in New Issue
Block a user