Add proper CMake setup and update project structure
This commit is contained in:
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/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;
|
||||
}
|
||||
44
src/Program.cpp
Normal file
44
src/Program.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 <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>
|
||||
|
||||
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>());
|
||||
}
|
||||
|
||||
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