Commit 15784af1 authored by amiessen's avatar amiessen
Browse files

added day 7, part 1

parent 145df2b2
CXX = g++
CXXFLAGS += -std=c++14
CXXFLAGS += -Wall -Wextra -Wpedantic
main07.exe: main07.cpp intCode.hpp
$(CXX) $(CXXFLAGS) $< -o $@
run: main07.exe
./main07.exe
clean:
rm -v *.exe out*.txt
.PHONY: run clean
3,8,1001,8,10,8,105,1,0,0,21,38,47,64,89,110,191,272,353,434,99999,3,9,101,4,9,9,102,3,9,9,101,5,9,9,4,9,99,3,9,1002,9,5,9,4,9,99,3,9,101,2,9,9,102,5,9,9,1001,9,5,9,4,9,99,3,9,1001,9,5,9,102,4,9,9,1001,9,5,9,1002,9,2,9,1001,9,3,9,4,9,99,3,9,102,2,9,9,101,4,9,9,1002,9,4,9,1001,9,4,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,99
#ifndef INTCODE_HPP
#define INTCODE_HPP
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
void setParaMode(std::vector<int *> & params,
std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
// set pointers to integers depending on parameter mode (1 or 0, position
// or immediate, respectively)
for (size_t i = 0; i < params.size(); i++) {
if (*(p_it+i) == 1) {
params[i] = &(*(code_it+pos+i));
} else {
params[i] = &(*(code_it + *(code_it+pos+i)));
}
}
}
// make template parameter for opcode (policies / expression templates)
void modify1(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(3);
setParaMode(params, p_it, code_it, pos);
*params[2] = (*params[0]) + (*params[1]);
}
void modify2(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(3);
setParaMode(params, p_it, code_it, pos);
*params[2] = (*params[0]) * (*params[1]);
}
void modify3(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
int input = 0;
std::vector<int *> params(1);
setParaMode(params, p_it, code_it, pos);
std::cin >> input;
*params[0] = input;
// std::cout << "Input: " << input << "\n";
}
int modify4(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(1);
setParaMode(params, p_it, code_it, pos);
// std::cout << "Output: " << *params[0] << "\n";
return *params[0];
}
size_t modify5(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(2);
setParaMode(params, p_it, code_it, pos);
if (*params[0] != 0) { return *params[1]; }
else { return pos + 2; }
}
size_t modify6(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(2);
setParaMode(params, p_it, code_it, pos);
if (*params[0] == 0) { return *params[1]; }
else { return pos + 2; }
}
void modify7(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(3);
setParaMode(params, p_it, code_it, pos);
if (*params[0] < *params[1]) { *params[2] = 1; } else { *params[2] = 0; }
}
void modify8(std::vector<int>::iterator p_it,
std::vector<int>::iterator code_it, const int & pos)
{
std::vector<int *> params(3);
setParaMode(params, p_it, code_it, pos);
if (*params[0] == *params[1]) { *params[2] = 1; } else { *params[2] = 0; }
}
void getParameterMode(const int & x, std::vector<int> & paraMode) {
// from first integer in instruction (of form ABCDE):
// - last two digits (DE) give opcode
// - other digits (ABC - read from right to left, so CBA) give parameter
// modes of parameters in instruction. Parameter mode can be 1 (immediate
// mode, meaning the parameter is taken by value), or 0 (position mode,
// meaning the parameter gives the position/index of the value)
// If no parameter modes are provided, they are set to default - 0
std::string xs = std::to_string(x);
if (xs.size() > 2) {
std::string ops = xs.substr(xs.size()-2);
paraMode.push_back(std::stoi(ops));
// 1002
for (int i = xs.size()-3; i >= 0; i--) {
paraMode.push_back(xs[i]-'0');
}
} else {
paraMode.push_back(x);
}
}
bool runIntCode(std::vector<int> code, int & out, const int start = 0) {
// out must be passed by referenc in order to write out without exiting
// runIntCode().
// start gives starting position in int code (default = 0).
// -----------------
size_t step = 4;
size_t i = start; // start iterating through intCode
while (i < code.size()) {
std::vector<int> paraMode;
getParameterMode(code[i], paraMode);
int opcode = paraMode[0];
if (opcode == 1 || opcode == 2 || opcode == 7 || opcode == 8) {
step = 4;
paraMode.resize(step);
} else if (opcode == 3 || opcode == 4) {
step = 2;
paraMode.resize(step);
} else if (opcode == 5 || opcode == 6) {
step = 3;
paraMode.resize(step);
}
if (opcode == 1) { // ALTERNATIVE: Expression templates
modify1(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 2) {
modify2(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 3) {
modify3(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 4) {
out = modify4(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 5) {
i = modify5(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 6) {
i = modify6(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 7) {
modify7(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 8) {
modify8(paraMode.begin()+1, code.begin(), i+1);
} else if (opcode == 99) {
std::cout << " --- PROGRAM HALTED (op 99) --- \n";
break;
}
else {
std::cout << "ERROR: something went wrong - opcode = " << opcode;
std::cout << "(must be in (1, 2, ..., 8, 99))\n";
}
if (opcode != 5 && opcode != 6) { i += step; }
}
}
#endif // INTCODE_HPP
#include <fstream>
#include <algorithm>
#include "intCode.hpp"
void readData(const std::string & data_path, std::vector<int> & data) {
std::ifstream inFile(data_path);
std::string val;
if (inFile.is_open()) {
while (getline(inFile, val, ',')) {
data.push_back(std::stoi(val));
}
inFile.close();
}
}
void ampSeries(std::vector<int> & initCode) {
// find phase settings for 5 amplifiers running int code (initCode)
// corresponding to the maximum output signal (output of int code) of
// the last amplifier.
// -------------------
// create output file for amplifier signals (int code output)
std::ofstream oFile;
oFile.open("outIntCode.txt");
oFile << 0 << "\n" << 0;
oFile.close();
std::vector<int> phase{0,1,2,3,4}; // or with std::iota
int maxOut = 0;
std::vector<int> maxPhase;
std::ifstream inout;
do {
int out = 0;
for (size_t i = 0; i < phase.size(); i++) {
std::cout << " ---- AMP " << i << " ---- \n";
oFile.open("outIntCode.txt");
oFile << phase[i] << "\n" << out;
oFile.close();
// redirect cin to file to read from that file at run time
inout.open("outIntCode.txt");
// save old buf (standard input) and redirect to inout buffer
auto cinbuf = std::cin.rdbuf(inout.rdbuf());
runIntCode(initCode, out);
inout.close();
}
if (out > maxOut) {
maxOut = out;
maxPhase = phase;
}
} while (std::next_permutation(phase.begin(), phase.end()));
std::cout << " -- -- -- -- -- -- -- -- -- -- -- -- -- \n";
std::cout << "Max output: " << maxOut << " with phase ";
for (auto & i: maxPhase)
std::cout << i;
std::cout << "\n";
}
int main() {
std::string data_path = "in07.txt";
std::vector<int> initCode;
readData(data_path, initCode);
ampSeries(initCode);
}
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,
27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment