From 37793aca787119aaa2e8cd555bfd750633ed563c Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Tue, 8 Dec 2020 00:34:32 -0500 Subject: [PATCH] Add part 2 solution --- day8/day8.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/day8/day8.cpp b/day8/day8.cpp index 99a660f..a908bfe 100644 --- a/day8/day8.cpp +++ b/day8/day8.cpp @@ -15,6 +15,9 @@ constexpr auto ACCUMULATOR_INSTRUCTION = "acc"; constexpr auto JUMP_INSTRUCTION = "jmp"; constexpr auto NOP_INSTRUCTION = "nop"; +/** + * Represents a single line of the program + */ class ProgramLine { public: ProgramLine(std::string instruction, int value) : instruction(instruction), value(value) { @@ -24,6 +27,10 @@ class ProgramLine { return this->instruction; } + void setInstruction(std::string instruction) { + this->instruction = instruction; + } + int getValue() const { return this->value; } @@ -44,6 +51,11 @@ std::vector readInput(const std::string &filename) { return input; } +/** + * Convert the input to ProgramLines + * @param input The puzzle input + * @return std::vector The input as ProgramLines + */ std::vector parseProgramLines(const std::vector &input) { std::vector lines; lines.reserve(input.size()); @@ -60,14 +72,20 @@ std::vector parseProgramLines(const std::vector &input return lines; } -int part1(const std::vector &lines) { +/** + * Run the given program, checking if it terminates normally + * @param lines The lines of the program + * @return std::pair The value of the accumulator and whether or not the program exited normally (true) or + * hit an infinite loop (false) + */ +std::pair runProgram(const std::vector &lines) { std::set visitedLines; int accumulator = 0; int programCounter = 0; - while (true) { + while (programCounter < lines.size()) { ProgramLine line = lines.at(programCounter); if (visitedLines.find(programCounter) != visitedLines.end()) { - return accumulator; + return std::pair(accumulator, false); } visitedLines.insert(programCounter); @@ -82,6 +100,33 @@ int part1(const std::vector &lines) { programCounter++; } + + return std::pair(accumulator, true); +} + +int part1(const std::vector &lines) { + return runProgram(lines).first; +} + +int part2(const std::vector &lines) { + for (auto it = lines.cbegin(); it != lines.end(); it++) { + if (it->getInstruction() != JUMP_INSTRUCTION && it->getInstruction() != NOP_INSTRUCTION) { + continue; + } + + std::vector mutatedLines(lines); + ProgramLine &instructionToMutate = mutatedLines.at(it - lines.cbegin()); + auto newInstruction = + instructionToMutate.getInstruction() == JUMP_INSTRUCTION ? NOP_INSTRUCTION : JUMP_INSTRUCTION; + instructionToMutate.setInstruction(newInstruction); + auto result = runProgram(mutatedLines); + // If the program terminated normally, we're done + if (result.second) { + return result.first; + } + } + + throw new std::invalid_argument("No solution in input"); } int main(int argc, char *argv[]) { @@ -94,4 +139,5 @@ int main(int argc, char *argv[]) { auto programLines = parseProgramLines(input); std::cout << part1(programLines) << std::endl; + std::cout << part2(programLines) << std::endl; }