Add day 23 part 1
parent
11249d06ee
commit
76f683ee8c
|
@ -0,0 +1,15 @@
|
||||||
|
CC=g++
|
||||||
|
BIN_NAME=day23
|
||||||
|
CCFLAGS=-o $(BIN_NAME) -g -std=c++17
|
||||||
|
LDFLAGS=
|
||||||
|
|
||||||
|
.PHONY: all, clean
|
||||||
|
|
||||||
|
all: $(BIN_NAME)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BIN_NAME)
|
||||||
|
|
||||||
|
$(BIN_NAME): day23.cpp
|
||||||
|
$(CC) $(CCFLAGS) $(LDFLAGS) day23.cpp
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
#include <boost/hana/any_of.hpp>
|
||||||
|
#include <boost/hana/ext/std/tuple.hpp>
|
||||||
|
#include <boost/hana/for_each.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
constexpr int NUM_CRAB_TURNS = 100;
|
||||||
|
|
||||||
|
std::vector<std::string> readInput(const std::string &filename) {
|
||||||
|
std::vector<std::string> input;
|
||||||
|
std::string line;
|
||||||
|
std::ifstream file(filename);
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
input.push_back(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> makeCupList(const std::string &inputLine) {
|
||||||
|
std::vector<int> cups;
|
||||||
|
std::transform(inputLine.cbegin(), inputLine.cend(), std::back_inserter(cups), [](char rawNum) {
|
||||||
|
if (rawNum < '0' || rawNum > '9') {
|
||||||
|
throw std::invalid_argument("Not numeric");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawNum - '0';
|
||||||
|
});
|
||||||
|
|
||||||
|
return cups;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<int, int, int> getPickedUpCups(int currentCupIndex, const std::vector<int> &cupList) {
|
||||||
|
return std::make_tuple(
|
||||||
|
cupList.at((currentCupIndex + 1) % cupList.size()),
|
||||||
|
cupList.at((currentCupIndex + 2) % cupList.size()),
|
||||||
|
cupList.at((currentCupIndex + 3) % cupList.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tuple, typename ValueType>
|
||||||
|
bool tupleContainsItem(Tuple tuple, ValueType value) {
|
||||||
|
return boost::hana::any_of(tuple, [value](ValueType item) { return item == value; });
|
||||||
|
}
|
||||||
|
|
||||||
|
int findDestinationCup(int currentCupIndex, const std::vector<int> &cupList) {
|
||||||
|
int currentCup = cupList.at(currentCupIndex);
|
||||||
|
std::tuple<int, int, int> pickedUpCups = getPickedUpCups(currentCupIndex, cupList);
|
||||||
|
auto cupMinMaxIterators = std::minmax_element(cupList.cbegin(), cupList.cend());
|
||||||
|
std::pair<int, int> cupMinMax = std::make_pair(*(cupMinMaxIterators.first), *(cupMinMaxIterators.second));
|
||||||
|
|
||||||
|
int destinationCup = currentCup;
|
||||||
|
do {
|
||||||
|
destinationCup--;
|
||||||
|
if (destinationCup < cupMinMax.first) {
|
||||||
|
destinationCup = cupMinMax.second;
|
||||||
|
}
|
||||||
|
} while (tupleContainsItem(pickedUpCups, destinationCup));
|
||||||
|
|
||||||
|
return destinationCup;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string makeFullCupLabel(const std::vector<int> cups) {
|
||||||
|
std::string output;
|
||||||
|
output.reserve(cups.size() - 1);
|
||||||
|
auto startIt = std::find(cups.cbegin(), cups.cend(), 1);
|
||||||
|
for (int i = (startIt - cups.begin() + 1) % cups.size(); cups.at(i) != 1; i = (i + 1) % cups.size()) {
|
||||||
|
output.push_back(cups.at(i) + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string part1(const std::string &inputLine) {
|
||||||
|
std::vector<int> cups = makeCupList(inputLine);
|
||||||
|
int currentCup = cups.front();
|
||||||
|
for (int i = 0; i < NUM_CRAB_TURNS; i++) {
|
||||||
|
auto currentCupIt = std::find(cups.cbegin(), cups.cend(), currentCup);
|
||||||
|
int destinationCup = findDestinationCup(currentCupIt - cups.cbegin(), cups);
|
||||||
|
std::tuple<int, int, int> pickedUpCups = getPickedUpCups(currentCupIt - cups.cbegin(), cups);
|
||||||
|
|
||||||
|
// Perform the cup moves
|
||||||
|
std::vector<int> newCups;
|
||||||
|
newCups.reserve(cups.size());
|
||||||
|
for (int cup : cups) {
|
||||||
|
if (tupleContainsItem(pickedUpCups, cup)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
newCups.push_back(cup);
|
||||||
|
// Copy the existing cups over
|
||||||
|
if (cup == destinationCup) {
|
||||||
|
boost::hana::for_each(pickedUpCups, [&newCups](int item) { newCups.push_back(item); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the new current cup
|
||||||
|
cups = std::move(newCups);
|
||||||
|
currentCupIt = std::find(cups.cbegin(), cups.cend(), currentCup);
|
||||||
|
if (currentCupIt + 1 == cups.cend()) {
|
||||||
|
currentCup = cups.front();
|
||||||
|
} else {
|
||||||
|
currentCup = *(currentCupIt + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeFullCupLabel(cups);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << argv[0] << " <input_file>" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto input = readInput(argv[1]);
|
||||||
|
|
||||||
|
std::cout << part1(input.at(0)) << std::endl;
|
||||||
|
}
|
Loading…
Reference in New Issue