This commit is contained in:
zv0n 2022-12-04 10:22:21 +01:00
parent 3da37bc8f5
commit 1db6a7e5b0
3 changed files with 547 additions and 0 deletions

22
24/CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
enable_language(CXX)
project(AoC24)
if(APPLE)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
endif()
if(WIN32)
add_executable(${CMAKE_PROJECT_NAME} WIN32)
else()
add_executable(${CMAKE_PROJECT_NAME})
endif()
target_sources(${CMAKE_PROJECT_NAME}
PRIVATE main.cpp
)

252
24/input Normal file
View File

@ -0,0 +1,252 @@
inp w
mul x 0
add x z
mod x 26
div z 1
add x 10
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 10
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 5
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 15
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 12
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 12
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 6
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -2
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 4
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 15
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 3
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 15
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 7
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 11
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -3
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 2
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 12
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 4
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y

273
24/main.cpp Normal file
View File

@ -0,0 +1,273 @@
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
enum InstructionType { INP, ADD, MUL, DIV, MOD, EQL };
class Instruction {
public:
Instruction(InstructionType type, int operand1, int operand2, bool op2_var)
: type(type), operand1(operand1), operand2(operand2),
operand2_is_variable(op2_var){};
void performInstruction(std::vector<int64_t> &registers, std::queue<int64_t> &input) {
auto op2 = operand2_is_variable ? registers[operand2] : operand2;
switch(type) {
case INP:
registers[operand1] = input.front();
input.pop();
break;
case ADD:
registers[operand1] += op2;
break;
case MUL:
registers[operand1] *= op2;
break;
case DIV:
registers[operand1] /= op2;
break;
case MOD:
registers[operand1] %= op2;
break;
case EQL:
registers[operand1] = registers[operand1] == op2 ? 1 : 0;
break;
}
}
int getOperand1() const {
return operand1;
}
int getOperand2() const {
return operand2;
}
private:
InstructionType type;
int operand1 = -1;
int operand2 = -1;
bool operand2_is_variable = false;
};
class ALU {
public:
ALU() {
registers = {0,0,0,0};
}
void addInstruction(const Instruction &instruction) {
instructions.push_back(instruction);
}
void addInput(int64_t in) {
input.push(in);
}
void reset() {
registers = {0,0,0,0};
while(!input.empty()) {
input.pop();
}
}
void performProgram() {
for(auto &instruction : instructions) {
instruction.performInstruction(registers, input);
}
}
int64_t getRegisterValue(int register_index) {
return registers[register_index];
}
const std::vector<Instruction> &getInstructions() const {
return instructions;
}
private:
std::vector<Instruction> instructions;
std::vector<int64_t> registers;
std::queue<int64_t> input;
};
ALU getALU(const std::string &file_name) {
std::ifstream file(file_name);
ALU result;
std::string str;
while (std::getline(file, str)) {
InstructionType type;
int operand1 = 0;
int operand2 = 0;
bool operand2_is_var = false;
if(str.substr(0, 3) == "add") {
type = ADD;
} else if(str.substr(0, 3) == "mul") {
type = MUL;
} else if(str.substr(0, 3) == "inp") {
type = INP;
} else if(str.substr(0, 3) == "div") {
type = DIV;
} else if(str.substr(0, 3) == "mod") {
type = MOD;
} else if(str.substr(0, 3) == "eql") {
type = EQL;
}
switch(str[4]) {
case 'w':
operand1 = 0;
break;
case 'x':
operand1 = 1;
break;
case 'y':
operand1 = 2;
break;
case 'z':
operand1 = 3;
break;
}
if(str[6] > '9') {
switch(str[6]) {
case 'w':
operand2 = 0;
break;
case 'x':
operand2 = 1;
break;
case 'y':
operand2 = 2;
break;
case 'z':
operand2 = 3;
break;
}
operand2_is_var = true;
} else {
std::string tmp;
std::stringstream ss(str);
ss >> tmp;
ss >> tmp;
ss >> operand2;
}
result.addInstruction(Instruction(type, operand1, operand2, operand2_is_var));
}
return result;
}
int64_t inputToInt(const int input[14]) {
int64_t result = 0;
for(int i = 0; i < 14; i++) {
result *= 10;
result += input[i];
}
return result;
}
void decreaseInput(int input[14]) {
int index = 13;
bool cont = false;
do {
cont = false;
input[index] -= 1;
if(input[index] == 0) {
input[index] = 9;
index--;
cont = true;
if(index < 0) {
return;
}
}
} while(cont);
if(index < 8) {
std::cout << inputToInt(input) << std::endl;
}
}
int64_t part1(ALU &alu) {
int input[14] = {9,9,9,9,9,9,9,9,9,9,9,9,9,9};
int vars[14][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
auto instructions = alu.getInstructions();
int index = 0;
for(int i = 5; i < instructions.size(); i+=18) {
vars[index][0] = instructions[i].getOperand2();
vars[index][1] = instructions[i+10].getOperand2();
index++;
}
std::vector<int> push;
for(int i = 0; i < 14; i++) {
if(vars[i][0] > 0) {
push.push_back(i);
} else {
auto in = input[push.back()] + vars[push.back()][1];
in += vars[i][0];
if(in < 0) {
std::cerr << "Something went horribly wrong" << std::endl;
exit(1);
}
while(in > 9) {
in--;
input[push.back()]--;
}
push.pop_back();
input[i] = in;
}
}
alu.reset();
for(int i = 0; i < 14; i++) {
alu.addInput(input[i]);
}
alu.performProgram();
if(alu.getRegisterValue(3) == 0) {
return inputToInt(input);
}
return -1;
}
uint64_t part2(ALU &alu) {
int input[14] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int vars[14][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
auto instructions = alu.getInstructions();
int index = 0;
for(int i = 5; i < instructions.size(); i+=18) {
vars[index][0] = instructions[i].getOperand2();
vars[index][1] = instructions[i+10].getOperand2();
index++;
}
std::vector<int> push;
for(int i = 0; i < 14; i++) {
if(vars[i][0] > 0) {
push.push_back(i);
} else {
auto in = input[push.back()] + vars[push.back()][1];
in += vars[i][0];
if(in > 9) {
std::cerr << "Something went horribly wrong" << std::endl;
exit(1);
}
while(in < 1) {
in++;
input[push.back()]++;
}
push.pop_back();
input[i] = in;
}
}
alu.reset();
for(int i = 0; i < 14; i++) {
alu.addInput(input[i]);
}
alu.performProgram();
if(alu.getRegisterValue(3) == 0) {
return inputToInt(input);
}
return -1;
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "You must provide input file!" << std::endl;
return 1;
}
auto alu = getALU(argv[1]);
std::cout << "The highest possible submarine number is \033[91;1m" << part1(alu)
<< "\033[0m." << std::endl;
std::cout << "The smallest possible submarine number is \033[91;1m" << part2(alu)
<< "\033[0m." << std::endl;
return 0;
}