From 5ce69e4dff3818342828244e3b05b2de2d9e8980 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sat, 14 Dec 2019 19:38:06 +0100 Subject: [PATCH] Finally remove the second intcode implementation. --- 2019/src/day02.cpp | 12 ++-- 2019/src/day05.cpp | 6 +- 2019/src/day09.cpp | 6 +- 2019/src/utils.cpp | 117 ++++++------------------------------ 2019/src/utils.hpp | 8 ++- 2019/tests/test_intcode.cpp | 2 +- 6 files changed, 37 insertions(+), 114 deletions(-) diff --git a/2019/src/day02.cpp b/2019/src/day02.cpp index 6164d4f..d251264 100644 --- a/2019/src/day02.cpp +++ b/2019/src/day02.cpp @@ -5,20 +5,22 @@ #include "days.hpp" #include "utils.hpp" -static int run_program(std::vector program) { - aoc2019::run_intcode(program); - return program[0]; +static int run_program(std::vector program) { + aoc2019::IntCodeComputer computer(std::move(program)); + computer.run(); + + return computer[0]; } void aoc2019::day02_part1(std::istream &input, std::ostream &output) { - auto program = read_intcode(input); + auto program = IntCodeComputer::read_intcode(input); program[1] = 12; program[2] = 2; output << run_program(std::move(program)) << std::endl; } void aoc2019::day02_part2(std::istream &input, std::ostream &output) { - auto program = read_intcode(input); + auto program = IntCodeComputer::read_intcode(input); for (int noun = 0; noun < 100; ++noun) { for (int verb = 0; verb < 100; ++verb) { diff --git a/2019/src/day05.cpp b/2019/src/day05.cpp index dcc1aab..aaa749d 100644 --- a/2019/src/day05.cpp +++ b/2019/src/day05.cpp @@ -3,13 +3,13 @@ #include "utils.hpp" void aoc2019::day05_part1(std::istream &input, std::ostream &output) { - auto program = read_intcode(input); - auto result = aoc2019::run_intcode(program, { 1 }); + auto program = IntCodeComputer::read_intcode(input); + auto result = run_intcode(program, { 1 }); output << result.back() << std::endl; } void aoc2019::day05_part2(std::istream &input, std::ostream &output) { - auto program = read_intcode(input); + auto program = IntCodeComputer::read_intcode(input); auto result = run_intcode(program, { 5 }); output << result.back() << std::endl; } diff --git a/2019/src/day09.cpp b/2019/src/day09.cpp index 58c04da..d1721ad 100644 --- a/2019/src/day09.cpp +++ b/2019/src/day09.cpp @@ -4,10 +4,9 @@ #include "utils.hpp" void aoc2019::day09_part1(std::istream &input, std::ostream &output) { - auto program = IntCodeComputer::read_intcode(input); std::deque outputs; - IntCodeComputer computer(std::move(program), { 1 }); + IntCodeComputer computer(input, { 1 }); computer.connectOutput(outputs); computer.run(); @@ -23,10 +22,9 @@ void aoc2019::day09_part1(std::istream &input, std::ostream &output) { } void aoc2019::day09_part2(std::istream &input, std::ostream &output) { - auto program = IntCodeComputer::read_intcode(input); std::deque outputs; - IntCodeComputer computer(std::move(program), { 2 }); + IntCodeComputer computer(input, { 2 }); computer.connectOutput(outputs); computer.run(); diff --git a/2019/src/utils.cpp b/2019/src/utils.cpp index 5db9c68..4cce9c2 100644 --- a/2019/src/utils.cpp +++ b/2019/src/utils.cpp @@ -12,106 +12,14 @@ std::string_view aoc2019::strtok(std::string_view &str, char token) { return next; } -std::vector aoc2019::run_intcode(std::vector &program, std::deque inputs) { - std::vector outputs{}; - int ip = 0; - auto interpret_value = [&program, &ip](int pos) { - bool immediate = false; - switch (pos) { - case 1: - immediate = program[ip] / 100 % 10; - break; - case 2: - immediate = program[ip] / 1000 % 10; - break; +std::deque aoc2019::run_intcode(std::vector program, std::deque inputs) { + std::deque outputs; + IntCodeComputer computer(std::move(program), std::move(inputs)); + computer.connectOutput(outputs); - case 3: - immediate = program[ip] / 10000 % 10; - break; + computer.run(); - default: - throw std::out_of_range("Invalid position"); - } - - if (immediate) { - return program[ip + pos]; - } else { - return program[program[ip + pos]]; - } - }; - - while (ip < program.size()) { - switch (program[ip] % 100) { - case 1: - program[program[ip + 3]] = interpret_value(1) + interpret_value(2); - ip += 4; - break; - - case 2: - program[program[ip + 3]] = interpret_value(1) * interpret_value(2); - ip += 4; - break; - - case 3: - if (inputs.empty()) { - throw std::out_of_range("No inputs left"); - } - program[program[ip + 1]] = inputs.front(); - inputs.pop_front(); - ip += 2; - break; - - case 4: - outputs.push_back(interpret_value(1)); - ip += 2; - break; - - case 5: // Jump if non-zero - if (interpret_value(1)) { - ip = interpret_value(2); - } else { - ip += 3; - } - break; - - case 6: // Jump if zero - if (!interpret_value(1)) { - ip = interpret_value(2); - } else { - ip += 3; - } - break; - - case 7: // equality - program[program[ip + 3]] = interpret_value(1) < interpret_value(2); - ip += 4; - break; - - case 8: // less than - program[program[ip + 3]] = interpret_value(1) == interpret_value(2) ? 1 : 0; - ip += 4; - break; - - case 99: - return outputs; - - default: - char buffer[30]; - std::snprintf(buffer, sizeof(buffer), "Invalid opcode: %d", program[ip]); - - throw std::domain_error(buffer); - } - } - throw std::out_of_range("Program read out of bounds"); -} - -std::vector aoc2019::read_intcode(std::istream &input) { - std::vector program{}; - for (int current; input >> current; input.ignore()) { - program.push_back(current); - } - - return program; + return outputs; } aoc2019::IntCodeComputer::value_t &aoc2019::IntCodeComputer::interpret_value(int pos) { @@ -259,6 +167,19 @@ aoc2019::IntCodeComputer::IntCodeComputer(std::vector program, std::deq program{std::move(program)}, inputs{std::move(initial_inputs)} { } + +aoc2019::IntCodeComputer::IntCodeComputer(std::istream &program_stream, std::deque initial_inputs) : + program(read_intcode(program_stream)), inputs(std::move(inputs)) { +} + void aoc2019::IntCodeComputer::sendInput(aoc2019::IntCodeComputer::value_t input) { inputs.push_back(input); } + +aoc2019::IntCodeComputer::value_t &aoc2019::IntCodeComputer::operator[](std::size_t index) { + return program[index]; +} + +const aoc2019::IntCodeComputer::value_t &aoc2019::IntCodeComputer::operator[](std::size_t index) const { + return program[index]; +} diff --git a/2019/src/utils.hpp b/2019/src/utils.hpp index a7f04d0..d39ed4e 100644 --- a/2019/src/utils.hpp +++ b/2019/src/utils.hpp @@ -23,9 +23,7 @@ namespace aoc2019 { std::string_view strtok(std::string_view &str, char token = ','); - std::vector read_intcode(std::istream &input); - - std::vector run_intcode(std::vector &program, std::deque inputs = {}); + std::deque run_intcode(std::vector program, std::deque inputs = {}); template std::vector topological_sort(const std::unordered_map> &edge_list) { @@ -75,6 +73,7 @@ namespace aoc2019 { typedef std::int64_t value_t; explicit IntCodeComputer(std::vector program, std::deque initial_inputs = {}); + explicit IntCodeComputer(std::istream &program_stream, std::deque initial_inputs = {}); void run(); void connectOutput(IntCodeComputer &computer); @@ -85,6 +84,9 @@ namespace aoc2019 { [[nodiscard]] const std::deque ¤tInputs() const; + value_t &operator[](std::size_t index); + const value_t &operator[](std::size_t index) const; + static std::vector read_intcode(std::istream &input); private: diff --git a/2019/tests/test_intcode.cpp b/2019/tests/test_intcode.cpp index a1ef0fa..a38290b 100644 --- a/2019/tests/test_intcode.cpp +++ b/2019/tests/test_intcode.cpp @@ -41,7 +41,7 @@ TEST(Intcode, TestImmediateLess) { } TEST(Intcode, TestComplicatedConditional) { - const std::vector program = {3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, + const std::vector program = {3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99}; auto pcopy = program;