Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Solutions for day 5 in C++
- Loading branch information
1 parent
6d3fc04
commit 6bdb425
Showing
5 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
g++ -std=c++17 5a.cpp -o 5a | ||
(cat input && echo "1") | ./5a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
g++ -std=c++17 5b.cpp -o 5b | ||
(cat input && echo "5") | ./5b |