From 649ced151547f5caa5ab8ac87becac146e65f615 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Wed, 25 Dec 2019 17:33:18 +0100 Subject: [PATCH] Split input reading from algorithm. --- 2019/src/day22.cpp | 83 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/2019/src/day22.cpp b/2019/src/day22.cpp index d58b110..0e77b25 100644 --- a/2019/src/day22.cpp +++ b/2019/src/day22.cpp @@ -3,6 +3,40 @@ #include "days.hpp" #include "utils.hpp" +namespace { + enum class Operation { + Stack, + Deal, + Cut + }; + + using Move = std::pair; + + std::vector read_moves(std::istream &input) { + std::string buffer; + std::vector moves; + + while (std::getline(input, buffer)) { + std::string_view line = buffer; + if (!line.find("deal into new stack")) { + moves.emplace_back(Operation::Stack, 0); + } else if (!line.find("deal with increment ")) { + int new_increment; + aoc2019::from_chars(line.substr(20), new_increment); + moves.emplace_back(Operation::Deal, new_increment); + } else { + // cut + int new_offset; + aoc2019::from_chars(line.substr(4), new_offset); + + moves.emplace_back(Operation::Cut, new_offset); + } + } + + return moves; + } +} + void aoc2019::day22_part1(std::istream &input, std::ostream &output) { constexpr int DECK_SIZE = 10007; @@ -11,32 +45,33 @@ void aoc2019::day22_part1(std::istream &input, std::ostream &output) { auto copy = deck; - std::string buffer; - while (std::getline(input, buffer)) { - std::string_view line = buffer; - if (!line.find("deal into new stack")) { - std::reverse(deck.begin(), deck.end()); - } else if (!line.find("deal with increment ")) { - int new_increment; - from_chars(line.substr(20), new_increment); - int pos = 0; - for (auto value : deck) { - copy[pos] = value; - pos = (pos + new_increment) % DECK_SIZE; - } - std::swap(deck, copy); - } else { - // cut - int new_offset; - from_chars(line.substr(4), new_offset); - if (new_offset < 0) { - new_offset = DECK_SIZE + new_offset; - } + for (auto move : read_moves(input)) { + int argument = move.second; + int pos; + switch (move.first) { + case Operation::Stack: + std::reverse(deck.begin(), deck.end()); + break; - auto it = std::copy(deck.begin() + new_offset, deck.end(), copy.begin()); - std::copy(deck.begin(), deck.begin() + new_offset, it); + case Operation::Deal: + pos = 0; + for (auto value : deck) { + copy[pos] = value; + pos = (pos + argument) % DECK_SIZE; + } + std::swap(deck, copy); + break; - std::swap(deck, copy); + case Operation::Cut: + if (argument < 0) { + argument += DECK_SIZE; + } + + auto it = std::copy(deck.begin() + argument, deck.end(), copy.begin()); + std::copy(deck.begin(), deck.begin() + argument, it); + + std::swap(deck, copy); + break; } }