Finally remove the second intcode implementation.

This commit is contained in:
2019-12-14 19:38:06 +01:00
parent 61f499e8e9
commit 5ce69e4dff
6 changed files with 37 additions and 114 deletions

View File

@@ -5,20 +5,22 @@
#include "days.hpp" #include "days.hpp"
#include "utils.hpp" #include "utils.hpp"
static int run_program(std::vector<int> program) { static int run_program(std::vector<std::int64_t> program) {
aoc2019::run_intcode(program); aoc2019::IntCodeComputer computer(std::move(program));
return program[0]; computer.run();
return computer[0];
} }
void aoc2019::day02_part1(std::istream &input, std::ostream &output) { 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[1] = 12;
program[2] = 2; program[2] = 2;
output << run_program(std::move(program)) << std::endl; output << run_program(std::move(program)) << std::endl;
} }
void aoc2019::day02_part2(std::istream &input, std::ostream &output) { 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 noun = 0; noun < 100; ++noun) {
for (int verb = 0; verb < 100; ++verb) { for (int verb = 0; verb < 100; ++verb) {

View File

@@ -3,13 +3,13 @@
#include "utils.hpp" #include "utils.hpp"
void aoc2019::day05_part1(std::istream &input, std::ostream &output) { void aoc2019::day05_part1(std::istream &input, std::ostream &output) {
auto program = read_intcode(input); auto program = IntCodeComputer::read_intcode(input);
auto result = aoc2019::run_intcode(program, { 1 }); auto result = run_intcode(program, { 1 });
output << result.back() << std::endl; output << result.back() << std::endl;
} }
void aoc2019::day05_part2(std::istream &input, std::ostream &output) { 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 }); auto result = run_intcode(program, { 5 });
output << result.back() << std::endl; output << result.back() << std::endl;
} }

View File

@@ -4,10 +4,9 @@
#include "utils.hpp" #include "utils.hpp"
void aoc2019::day09_part1(std::istream &input, std::ostream &output) { void aoc2019::day09_part1(std::istream &input, std::ostream &output) {
auto program = IntCodeComputer::read_intcode(input);
std::deque<std::int64_t> outputs; std::deque<std::int64_t> outputs;
IntCodeComputer computer(std::move(program), { 1 }); IntCodeComputer computer(input, { 1 });
computer.connectOutput(outputs); computer.connectOutput(outputs);
computer.run(); 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) { void aoc2019::day09_part2(std::istream &input, std::ostream &output) {
auto program = IntCodeComputer::read_intcode(input);
std::deque<std::int64_t> outputs; std::deque<std::int64_t> outputs;
IntCodeComputer computer(std::move(program), { 2 }); IntCodeComputer computer(input, { 2 });
computer.connectOutput(outputs); computer.connectOutput(outputs);
computer.run(); computer.run();

View File

@@ -12,106 +12,14 @@ std::string_view aoc2019::strtok(std::string_view &str, char token) {
return next; return next;
} }
std::vector<int> aoc2019::run_intcode(std::vector<int> &program, std::deque<int> inputs) { std::deque<int64_t> aoc2019::run_intcode(std::vector<int64_t> program, std::deque<int64_t> inputs) {
std::vector<int> outputs{}; std::deque<std::int64_t> outputs;
int ip = 0; IntCodeComputer computer(std::move(program), std::move(inputs));
auto interpret_value = [&program, &ip](int pos) { computer.connectOutput(outputs);
bool immediate = false;
switch (pos) {
case 1:
immediate = program[ip] / 100 % 10;
break;
case 2:
immediate = program[ip] / 1000 % 10;
break;
case 3: computer.run();
immediate = program[ip] / 10000 % 10;
break;
default: return outputs;
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<int> aoc2019::read_intcode(std::istream &input) {
std::vector<int> program{};
for (int current; input >> current; input.ignore()) {
program.push_back(current);
}
return program;
} }
aoc2019::IntCodeComputer::value_t &aoc2019::IntCodeComputer::interpret_value(int pos) { aoc2019::IntCodeComputer::value_t &aoc2019::IntCodeComputer::interpret_value(int pos) {
@@ -259,6 +167,19 @@ aoc2019::IntCodeComputer::IntCodeComputer(std::vector<value_t> program, std::deq
program{std::move(program)}, inputs{std::move(initial_inputs)} { program{std::move(program)}, inputs{std::move(initial_inputs)} {
} }
aoc2019::IntCodeComputer::IntCodeComputer(std::istream &program_stream, std::deque<value_t> initial_inputs) :
program(read_intcode(program_stream)), inputs(std::move(inputs)) {
}
void aoc2019::IntCodeComputer::sendInput(aoc2019::IntCodeComputer::value_t input) { void aoc2019::IntCodeComputer::sendInput(aoc2019::IntCodeComputer::value_t input) {
inputs.push_back(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];
}

View File

@@ -23,9 +23,7 @@ namespace aoc2019 {
std::string_view strtok(std::string_view &str, char token = ','); std::string_view strtok(std::string_view &str, char token = ',');
std::vector<int> read_intcode(std::istream &input); std::deque<int64_t> run_intcode(std::vector<std::int64_t> program, std::deque<std::int64_t> inputs = {});
std::vector<int> run_intcode(std::vector<int> &program, std::deque<int> inputs = {});
template<class Node> template<class Node>
std::vector<Node> topological_sort(const std::unordered_map<Node, std::vector<Node>> &edge_list) { std::vector<Node> topological_sort(const std::unordered_map<Node, std::vector<Node>> &edge_list) {
@@ -75,6 +73,7 @@ namespace aoc2019 {
typedef std::int64_t value_t; typedef std::int64_t value_t;
explicit IntCodeComputer(std::vector<value_t> program, std::deque<value_t> initial_inputs = {}); explicit IntCodeComputer(std::vector<value_t> program, std::deque<value_t> initial_inputs = {});
explicit IntCodeComputer(std::istream &program_stream, std::deque<value_t> initial_inputs = {});
void run(); void run();
void connectOutput(IntCodeComputer &computer); void connectOutput(IntCodeComputer &computer);
@@ -85,6 +84,9 @@ namespace aoc2019 {
[[nodiscard]] const std::deque<value_t> &currentInputs() const; [[nodiscard]] const std::deque<value_t> &currentInputs() const;
value_t &operator[](std::size_t index);
const value_t &operator[](std::size_t index) const;
static std::vector<value_t> read_intcode(std::istream &input); static std::vector<value_t> read_intcode(std::istream &input);
private: private:

View File

@@ -41,7 +41,7 @@ TEST(Intcode, TestImmediateLess) {
} }
TEST(Intcode, TestComplicatedConditional) { TEST(Intcode, TestComplicatedConditional) {
const std::vector<int> program = {3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, const std::vector<std::int64_t> 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, 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}; 999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99};
auto pcopy = program; auto pcopy = program;