Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Solutions for day 5 in C++
  • Loading branch information
carl-westerlund committed Dec 5, 2019
1 parent 6d3fc04 commit 6bdb425
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 0 deletions.
138 changes: 138 additions & 0 deletions nerarith-c++/day5/5a.cpp
@@ -0,0 +1,138 @@
#include <bits/stdc++.h>
#include "prettyprint.hpp"
using namespace std;

const int MAX_NUM_PARAMETERS = 3;

set<int> known_opcodes = {1, 2, 3, 4, 99};
map<int, int> num_parameters_for_opcode = {
{1, 3},
{2, 3},
{3, 1},
{4, 1},
{99, 0}
};
vector<int> memory;
int memory_size;
int memory_get (int address) {
if (0 <= address && address < memory_size)
return memory[address];
else {
cerr << "error: out of bounds with address " << address << endl;
return -1;
}
}
void memory_set (int address, int value) {
if (0 <= address && address < memory_size)
memory[address] = value;
else
cerr << "error: out of bounds with address " << address << endl;
}

pair<int, vector<int>> extract_opcode_parameter_modes (int address) {
int combined = memory_get(address);
int opcode = combined % 100;
combined /= 100;
vector<int> parameter_modes (3);
for (int i=0; i < MAX_NUM_PARAMETERS; i++) {
parameter_modes[i] = combined % 10;
combined /= 10;
}
return {opcode, parameter_modes};
}

const int PARAMETER_MODE_POSITION = 0;
const int PARAMETER_MODE_IMMEDIATE = 1;

vector<int> get_parameters (int address, int num_parameters, vector<int> parameter_modes) {
vector<int> parameter_addresses (num_parameters);
for (int i=0; i < num_parameters; i++) {
switch (parameter_modes[i]) {
case PARAMETER_MODE_POSITION:
{
parameter_addresses[i] = memory_get(address+i);
break;
}
case PARAMETER_MODE_IMMEDIATE:
{
parameter_addresses[i] = address+i;
break;
}
}
}
return parameter_addresses;
}

const int OPCODE_ADD = 1;
const int OPCODE_MULTIPLY = 2;
const int OPCODE_INPUT = 3;
const int OPCODE_OUTPUT = 4;
const int OPCODE_HALT = 99;

int execute_operation(int opcode, vector<int> parameter_addresses) {
switch (opcode) {
case OPCODE_ADD:
{
int term1 = memory_get(parameter_addresses[0]);
int term2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];

int output = term1 + term2;
memory_set(output_address, output);
break;
}
case OPCODE_MULTIPLY:
{
int factor1 = memory_get(parameter_addresses[0]);
int factor2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];

int output = factor1 * factor2;
memory_set(output_address, output);
break;
}
case OPCODE_INPUT:
{
int output_address = parameter_addresses[0];
int input;
cin >> input;
memory_set(output_address, input);
break;
}
case OPCODE_OUTPUT:
{
int input_address = parameter_addresses[0];
int output = memory_get(input_address);
cout << output << endl;
break;
}
case OPCODE_HALT:
{
return -1;
}
}
return 0;
}

int main() {
int code;
char comma;
while (cin >> code) {
memory.push_back(code);
if (cin.peek() == ',')
cin >> comma;
else
break;
}
memory_size = memory.size();

int address = 0;
while (address < memory_size) {
auto [opcode, parameter_modes] = extract_opcode_parameter_modes(address);
vector<int> parameter_addresses = get_parameters(address+1, num_parameters_for_opcode[opcode], parameter_modes);
if (execute_operation(opcode, parameter_addresses) == -1)
break;
address += 1+num_parameters_for_opcode[opcode];
}
}

194 changes: 194 additions & 0 deletions nerarith-c++/day5/5b.cpp
@@ -0,0 +1,194 @@
#include <bits/stdc++.h>
#include "prettyprint.hpp"
using namespace std;

const int MAX_NUM_PARAMETERS = 3;

set<int> known_opcodes = {1, 2, 3, 4, 5, 6, 7, 8, 99};
map<int, int> num_parameters_for_opcode = {
{1, 3},
{2, 3},
{3, 1},
{4, 1},
{5, 2},
{6, 2},
{7, 3},
{8, 3},
{99, 0}
};
vector<int> memory;
int memory_size;
int memory_get (int address) {
if (0 <= address && address < memory_size)
return memory[address];
else {
cerr << "error: out of bounds with address " << address << endl;
return -1;
}
}
void memory_set (int address, int value) {
if (0 <= address && address < memory_size)
memory[address] = value;
else
cerr << "error: out of bounds with address " << address << endl;
}

pair<int, vector<int>> extract_opcode_parameter_modes (int address) {
int combined = memory_get(address);
int opcode = combined % 100;
combined /= 100;
vector<int> parameter_modes (3);
for (int i=0; i < MAX_NUM_PARAMETERS; i++) {
parameter_modes[i] = combined % 10;
combined /= 10;
}
return {opcode, parameter_modes};
}

const int PARAMETER_MODE_POSITION = 0;
const int PARAMETER_MODE_IMMEDIATE = 1;

vector<int> get_parameters (int address, int num_parameters, vector<int> parameter_modes) {
vector<int> parameter_addresses (num_parameters);
for (int i=0; i < num_parameters; i++) {
switch (parameter_modes[i]) {
case PARAMETER_MODE_POSITION:
{
parameter_addresses[i] = memory_get(address+i);
break;
}
case PARAMETER_MODE_IMMEDIATE:
{
parameter_addresses[i] = address+i;
break;
}
}
}
return parameter_addresses;
}

const int OPCODE_ADD = 1;
const int OPCODE_MULTIPLY = 2;
const int OPCODE_INPUT = 3;
const int OPCODE_OUTPUT = 4;
const int OPCODE_JUMP_IF_TRUE = 5;
const int OPCODE_JUMP_IF_FALSE = 6;
const int OPCODE_LESS_THAN = 7;
const int OPCODE_EQUALS = 8;
const int OPCODE_HALT = 99;

pair<bool, int> execute_operation(int opcode, vector<int> parameter_addresses) {
bool halt = false;
int new_address = -1;
switch (opcode) {
case OPCODE_ADD:
{
int term1 = memory_get(parameter_addresses[0]);
int term2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];

int output = term1 + term2;
memory_set(output_address, output);
break;
}
case OPCODE_MULTIPLY:
{
int factor1 = memory_get(parameter_addresses[0]);
int factor2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];

int output = factor1 * factor2;
memory_set(output_address, output);
break;
}
case OPCODE_INPUT:
{
int output_address = parameter_addresses[0];
int input;
cin >> input;
memory_set(output_address, input);
break;
}
case OPCODE_OUTPUT:
{
int input_address = parameter_addresses[0];
int output = memory_get(input_address);
cout << output << endl;
break;
}
case OPCODE_JUMP_IF_TRUE:
{
int condition = memory_get(parameter_addresses[0]);
if (condition != 0)
new_address = memory_get(parameter_addresses[1]);
break;
}
case OPCODE_JUMP_IF_FALSE:
{
int condition = memory_get(parameter_addresses[0]);
if (condition == 0)
new_address = memory_get(parameter_addresses[1]);
break;
}
case OPCODE_LESS_THAN:
{
int number1 = memory_get(parameter_addresses[0]);
int number2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];
int result;
if (number1 < number2)
result = 1;
else
result = 0;
memory_set(output_address, result);
break;
}
case OPCODE_EQUALS:
{
int number1 = memory_get(parameter_addresses[0]);
int number2 = memory_get(parameter_addresses[1]);
int output_address = parameter_addresses[2];
int result;
if (number1 == number2)
result = 1;
else
result = 0;
memory_set(output_address, result);
break;
}
case OPCODE_HALT:
{
halt = true;
break;
}
}
return {halt, new_address};
}

int main() {
int code;
char comma;
while (cin >> code) {
memory.push_back(code);
if (cin.peek() == ',')
cin >> comma;
else
break;
}
memory_size = memory.size();

int address = 0;
while (address < memory_size) {
auto [opcode, parameter_modes] = extract_opcode_parameter_modes(address);
vector<int> parameter_addresses = get_parameters(address+1, num_parameters_for_opcode[opcode], parameter_modes);

auto [halt, new_address] = execute_operation(opcode, parameter_addresses);
if (halt)
break;

if (new_address != -1)
address = new_address;
else
address += 1+num_parameters_for_opcode[opcode];
}
}
1 change: 1 addition & 0 deletions nerarith-c++/day5/input
@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1101,48,82,225,102,59,84,224,1001,224,-944,224,4,224,102,8,223,223,101,6,224,224,1,223,224,223,1101,92,58,224,101,-150,224,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1102,10,89,224,101,-890,224,224,4,224,1002,223,8,223,1001,224,5,224,1,224,223,223,1101,29,16,225,101,23,110,224,1001,224,-95,224,4,224,102,8,223,223,1001,224,3,224,1,223,224,223,1102,75,72,225,1102,51,8,225,1102,26,16,225,1102,8,49,225,1001,122,64,224,1001,224,-113,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1102,55,72,225,1002,174,28,224,101,-896,224,224,4,224,1002,223,8,223,101,4,224,224,1,224,223,223,1102,57,32,225,2,113,117,224,101,-1326,224,224,4,224,102,8,223,223,101,5,224,224,1,223,224,223,1,148,13,224,101,-120,224,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,677,226,224,102,2,223,223,1006,224,329,101,1,223,223,107,677,677,224,1002,223,2,223,1006,224,344,101,1,223,223,8,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,107,226,226,224,102,2,223,223,1005,224,374,1001,223,1,223,1108,677,226,224,1002,223,2,223,1006,224,389,101,1,223,223,107,677,226,224,102,2,223,223,1006,224,404,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,419,1001,223,1,223,108,677,677,224,102,2,223,223,1005,224,434,1001,223,1,223,1008,677,226,224,1002,223,2,223,1006,224,449,1001,223,1,223,7,226,677,224,1002,223,2,223,1006,224,464,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,479,1001,223,1,223,1007,226,226,224,1002,223,2,223,1005,224,494,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,509,1001,223,1,223,1007,226,677,224,1002,223,2,223,1006,224,524,101,1,223,223,1107,677,677,224,102,2,223,223,1005,224,539,101,1,223,223,1107,677,226,224,102,2,223,223,1005,224,554,1001,223,1,223,108,677,226,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,226,677,224,1002,223,2,223,1006,224,584,101,1,223,223,8,677,677,224,1002,223,2,223,1006,224,599,1001,223,1,223,1008,226,226,224,102,2,223,223,1006,224,614,101,1,223,223,7,677,677,224,1002,223,2,223,1006,224,629,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,644,101,1,223,223,7,677,226,224,1002,223,2,223,1005,224,659,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226
2 changes: 2 additions & 0 deletions nerarith-c++/day5/run_5a
@@ -0,0 +1,2 @@
g++ -std=c++17 5a.cpp -o 5a
(cat input && echo "1") | ./5a
2 changes: 2 additions & 0 deletions nerarith-c++/day5/run_5b
@@ -0,0 +1,2 @@
g++ -std=c++17 5b.cpp -o 5b
(cat input && echo "5") | ./5b

0 comments on commit 6bdb425

Please sign in to comment.