From 1db6a7e5b037d499df81045cf9d4741873771ef7 Mon Sep 17 00:00:00 2001 From: zv0n Date: Sun, 4 Dec 2022 10:22:21 +0100 Subject: [PATCH] 24 --- 24/CMakeLists.txt | 22 ++++ 24/input | 252 ++++++++++++++++++++++++++++++++++++++++++ 24/main.cpp | 273 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 547 insertions(+) create mode 100644 24/CMakeLists.txt create mode 100644 24/input create mode 100644 24/main.cpp diff --git a/24/CMakeLists.txt b/24/CMakeLists.txt new file mode 100644 index 0000000..62935d2 --- /dev/null +++ b/24/CMakeLists.txt @@ -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 + ) diff --git a/24/input b/24/input new file mode 100644 index 0000000..ea46334 --- /dev/null +++ b/24/input @@ -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 diff --git a/24/main.cpp b/24/main.cpp new file mode 100644 index 0000000..fcb2de5 --- /dev/null +++ b/24/main.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#include + +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 ®isters, std::queue &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 &getInstructions() const { + return instructions; + } +private: + std::vector instructions; + std::vector registers; + std::queue 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 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 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; +}