diff --git a/day24/Makefile b/day24/Makefile new file mode 100644 index 0000000..d854870 --- /dev/null +++ b/day24/Makefile @@ -0,0 +1,15 @@ +CC=g++ +BIN_NAME=day24 +CCFLAGS=-o $(BIN_NAME) -g -O2 -std=c++17 +LDFLAGS= + +.PHONY: all, clean + +all: $(BIN_NAME) + +clean: + rm -f $(BIN_NAME) + +$(BIN_NAME): day24.cpp + $(CC) $(CCFLAGS) $(LDFLAGS) day24.cpp + diff --git a/day24/day24.cpp b/day24/day24.cpp new file mode 100644 index 0000000..932d110 --- /dev/null +++ b/day24/day24.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include + +enum Direction { EAST, WEST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST, NORTH_EAST }; + +constexpr auto DIRECTION_PATTERN = R"(e|w|se|sw|nw|ne)"; +const std::map INPUT_TO_DIRECTION{ + std::make_pair("e", EAST), + std::make_pair("w", WEST), + std::make_pair("se", SOUTH_EAST), + std::make_pair("sw", SOUTH_WEST), + std::make_pair("nw", NORTH_WEST), + std::make_pair("ne", NORTH_EAST), +}; + +const std::map> DIRECTION_TO_DELTA{ + std::make_pair(EAST, std::make_pair(-2, 0)), + std::make_pair(WEST, std::make_pair(2, 0)), + std::make_pair(SOUTH_EAST, std::make_pair(-1, -1)), + std::make_pair(SOUTH_WEST, std::make_pair(1, -1)), + std::make_pair(NORTH_WEST, std::make_pair(1, 1)), + std::make_pair(NORTH_EAST, std::make_pair(-1, 1)), +}; + +std::vector readInput(const std::string &filename) { + std::vector input; + std::string line; + std::ifstream file(filename); + while (std::getline(file, line)) { + input.push_back(line); + } + + return input; +} + +std::vector parseInputLine(const std::string &inputLine) { + std::regex directionPattern(DIRECTION_PATTERN); + std::vector res; + std::transform( + std::sregex_iterator(inputLine.cbegin(), inputLine.cend(), directionPattern), + std::sregex_iterator(), + std::back_inserter(res), + [](const std::smatch &match) { + std::string directionStr = match.str(); + return INPUT_TO_DIRECTION.at(directionStr); + }); + + return res; +} + +std::vector> parseInput(const std::vector &input) { + std::vector> res; + std::transform(input.cbegin(), input.cend(), std::back_inserter(res), parseInputLine); + + return res; +} + +template +std::pair getPosition(Iter start, Iter end) { + return std::accumulate(start, end, std::make_pair(0, 0), [](std::pair position, const Direction &dir) { + std::pair delta = DIRECTION_TO_DELTA.at(dir); + return std::make_pair(position.first + delta.first, position.second + delta.second); + }); +} + +int part1(const std::vector> &input) { + std::map, bool> flipped; + for (const std::vector &sequence : input) { + std::pair pos = getPosition(sequence.cbegin(), sequence.cend()); + flipped[pos] = !flipped[pos]; + } + + return std::count_if(flipped.cbegin(), flipped.cend(), [](auto entry) { return entry.second; }); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + std::cerr << argv[0] << " " << std::endl; + return 1; + } + + auto input = readInput(argv[1]); + auto parsedInput = parseInput(input); + + std::cout << part1(parsedInput) << std::endl; +}