#include "common/aoc.h" namespace y2016::day12 { enum class Operator { Cpy, Inc, Dec, Jnz }; struct Instruction { Operator op; std::variant arg1; std::variant arg2; }; REGISTER_DAY(2016, Day12, std::vector, int); REGISTER_TEST_EXAMPLE(2016, Day12, ExampleInput, 1, 42); REGISTER_TEST(2016, Day12, Input, 1, 318007); REGISTER_TEST_EXAMPLE(2016, Day12, ExampleInput, 2, 42); REGISTER_TEST(2016, Day12, Input, 2, 9227661); READ_INPUT(input) { std::vector vec; std::string str; while (getline(input, str)) { Instruction instruction; if (str[0] == 'c') { instruction.op = Operator::Cpy; if (str[4] >= 'a' && str[4] <= 'd') instruction.arg1 = str[4]; else instruction.arg1 = (int)std::atoi(str.c_str() + 4); instruction.arg2 = str[str.size() - 1]; } else if (str[0] == 'i') { instruction.op = Operator::Inc; instruction.arg1 = str[4]; } else if (str[0] == 'd') { instruction.op = Operator::Dec; instruction.arg1 = str[4]; } else if (str[0] == 'j') { instruction.op = Operator::Jnz; if (str[4] >= 'a' && str[4] <= 'd') instruction.arg1 = str[4]; else instruction.arg1 = (int)std::atoi(str.c_str() + 4); instruction.arg2 = atoi(str.c_str() + 6); } vec.emplace_back(instruction); } return vec; } int Run(const std::vector& instructions, std::vector registers) { size_t pc = 0; while (pc < instructions.size()) { switch (instructions[pc].op) { case Operator::Cpy: { int number = 0; if (std::holds_alternative(instructions[pc].arg1)) number = std::get(instructions[pc].arg1); else number = registers[std::get(instructions[pc].arg1) - 'a']; registers[std::get(instructions[pc].arg2) - 'a'] = number; break; } case Operator::Inc: registers[std::get(instructions[pc].arg1) - 'a']++; break; case Operator::Dec: registers[std::get(instructions[pc].arg1) - 'a']--; break; case Operator::Jnz: int value = 0; if (std::holds_alternative(instructions[pc].arg1)) value = std::get(instructions[pc].arg1); else value = registers[std::get(instructions[pc].arg1) - 'a']; if (value != 0) pc += std::get(instructions[pc].arg2) - 1; break; } pc++; } return registers[0]; } OUTPUT1(input) { return Run(input, std::vector(4)); } OUTPUT2(input) { std::vector registers(4); registers[2] = 1; return Run(input, registers); } }