To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit c0fd09cd authored by amiessen's avatar amiessen
Browse files

added day 9, part 1

parent eb1a61f2
CXX = g++
CXXFLAGS += -std=c++14
CXXFLAGS += -Wall -Wextra -Wpedantic
main09.exe: main09.cpp intCode.hpp
$(CXX) $(CXXFLAGS) $< -o $@
run: main09.exe
./main09.exe
clean:
rm -v *.exe
.PHONY: run clean
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,1,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,0,0,1020,1101,34,0,1004,1101,0,26,1008,1102,1,37,1011,1101,39,0,1018,1102,587,1,1022,1101,1,0,1021,1102,22,1,1012,1101,0,33,1014,1101,24,0,1016,1101,0,752,1029,1101,36,0,1002,1101,35,0,1006,1101,32,0,1009,1102,38,1,1003,1102,584,1,1023,1101,0,20,1001,1102,892,1,1025,1102,29,1,1000,1101,411,0,1026,1102,1,901,1024,1101,0,761,1028,1101,23,0,1017,1102,30,1,1013,1101,0,27,1015,1102,28,1,1005,1101,408,0,1027,1101,25,0,1007,1102,31,1,1019,1101,0,21,1010,109,5,1207,-2,39,63,1005,63,199,4,187,1105,1,203,1001,64,1,64,1002,64,2,64,109,12,21102,40,1,-1,1008,1016,40,63,1005,63,229,4,209,1001,64,1,64,1106,0,229,1002,64,2,64,109,-5,1207,-5,24,63,1005,63,249,1001,64,1,64,1106,0,251,4,235,1002,64,2,64,109,-14,2102,1,6,63,1008,63,32,63,1005,63,271,1106,0,277,4,257,1001,64,1,64,1002,64,2,64,109,2,1202,1,1,63,1008,63,20,63,1005,63,303,4,283,1001,64,1,64,1106,0,303,1002,64,2,64,109,7,2108,34,2,63,1005,63,319,1106,0,325,4,309,1001,64,1,64,1002,64,2,64,109,6,2101,0,-6,63,1008,63,24,63,1005,63,349,1001,64,1,64,1105,1,351,4,331,1002,64,2,64,109,4,21107,41,42,0,1005,1017,369,4,357,1105,1,373,1001,64,1,64,1002,64,2,64,109,5,21101,42,0,-5,1008,1017,41,63,1005,63,397,1001,64,1,64,1106,0,399,4,379,1002,64,2,64,109,9,2106,0,-4,1106,0,417,4,405,1001,64,1,64,1002,64,2,64,109,-20,21108,43,43,0,1005,1011,435,4,423,1105,1,439,1001,64,1,64,1002,64,2,64,109,-15,2102,1,8,63,1008,63,34,63,1005,63,465,4,445,1001,64,1,64,1105,1,465,1002,64,2,64,109,3,1201,6,0,63,1008,63,28,63,1005,63,491,4,471,1001,64,1,64,1106,0,491,1002,64,2,64,109,18,21108,44,46,0,1005,1017,511,1001,64,1,64,1106,0,513,4,497,1002,64,2,64,109,12,1205,-8,527,4,519,1105,1,531,1001,64,1,64,1002,64,2,64,109,-17,1208,-3,32,63,1005,63,553,4,537,1001,64,1,64,1105,1,553,1002,64,2,64,109,-13,1208,10,31,63,1005,63,573,1001,64,1,64,1105,1,575,4,559,1002,64,2,64,109,17,2105,1,7,1105,1,593,4,581,1001,64,1,64,1002,64,2,64,109,-8,2107,19,-7,63,1005,63,615,4,599,1001,64,1,64,1105,1,615,1002,64,2,64,109,4,1206,8,629,4,621,1106,0,633,1001,64,1,64,1002,64,2,64,109,-2,2101,0,-6,63,1008,63,34,63,1005,63,655,4,639,1105,1,659,1001,64,1,64,1002,64,2,64,109,10,1205,0,671,1105,1,677,4,665,1001,64,1,64,1002,64,2,64,109,-21,2107,26,8,63,1005,63,693,1106,0,699,4,683,1001,64,1,64,1002,64,2,64,109,19,1201,-9,0,63,1008,63,30,63,1005,63,719,1105,1,725,4,705,1001,64,1,64,1002,64,2,64,109,9,1206,-6,741,1001,64,1,64,1106,0,743,4,731,1002,64,2,64,109,-5,2106,0,6,4,749,1001,64,1,64,1105,1,761,1002,64,2,64,109,-14,1202,-1,1,63,1008,63,27,63,1005,63,781,1105,1,787,4,767,1001,64,1,64,1002,64,2,64,109,1,21107,45,44,5,1005,1014,807,1001,64,1,64,1105,1,809,4,793,1002,64,2,64,109,8,21101,46,0,0,1008,1017,46,63,1005,63,835,4,815,1001,64,1,64,1106,0,835,1002,64,2,64,109,-26,2108,20,10,63,1005,63,857,4,841,1001,64,1,64,1106,0,857,1002,64,2,64,109,24,21102,47,1,-5,1008,1010,46,63,1005,63,881,1001,64,1,64,1106,0,883,4,863,1002,64,2,64,109,6,2105,1,3,4,889,1001,64,1,64,1105,1,901,4,64,99,21102,27,1,1,21101,915,0,0,1105,1,922,21201,1,29830,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1105,1,922,21202,1,1,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1105,1,968,21201,-2,0,-2,109,-3,2106,0,0
#ifndef INTCODE_HPP
#define INTCODE_HPP
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <type_traits>
// Type Traits
// template<typename T> struct intCode_type<T> { typedef T type; }
// template<> struct intCode_type<int> { typedef int type; }
template<typename T>
class intCode {
public:
static_assert(std::is_same<int, T>::value ||
std::is_same<long, T>::value ||
std::is_same<long long, T>::value,
"ERROR: class intCode must be called with template\
parameter of type <signed int>, i.e., int, long, etc.");
// Ctor
intCode(std::vector<T> code, bool stopAtOutput = false,
size_t pos = 0)
{
code_ = code;
lastOut_ = 0;
stopAtOutput_ = stopAtOutput;
pos_ = pos;
input_ = 0;
inputCount_ = 0;
relBase_ = 0;
}
// Getters
size_t getPosition() { return pos_; }
std::vector<T> getCode() { return code_; }
T getOutput() { return lastOut_; }
// Public Member
bool runIntCode(const std::vector<T> &);
private:
size_t pos_; // where in int code am I
size_t inputCount_;
T relBase_;
T lastOut_;
T input_;
std::vector<T> code_;
std::vector<int> paraMode_;
bool stopAtOutput_;
// Private Member
void getParameterMode();
void setParaMode(std::vector<T *> &);
void modify1();
void modify2();
void modify3();
void modify4();
void modify5();
void modify6();
void modify7();
void modify8();
void modify9();
};
template<typename T>
void intCode<T>::setParaMode(std::vector<T *> & params)
{
// set pointers to integers depending on parameter mode
// 0 - position mode
// (parameter interpreted as position of value)
// 1 - immediate mode
// (parameter interpreted as value)
// 2 - relative mode
// (parameter is interpreted as position, value is at
// position + relative base)
for (size_t i = 0; i < params.size(); i++) {
if (*(paraMode_.begin()+1+i) == 0) { // position mode
params[i] = &( *(code_.begin() + *(code_.begin() + pos_+1+i) ) );
} else if (*(paraMode_.begin()+1+i) == 1) { // immediate mode
params[i] = &( *(code_.begin() + pos_+1+i) );
} else if (*(paraMode_.begin()+1+i) == 2) { // relative mode
params[i] = &( *(code_.begin() + *(code_.begin() + pos_+1+i) + relBase_) );
}
}
}
template<typename T>
void intCode<T>::modify1()
{
std::vector<T *> params(3);
setParaMode(params);
*params[2] = (*params[0]) + (*params[1]);
}
template<typename T>
void intCode<T>::modify2()
{
std::vector<T *> params(3);
setParaMode(params);
*params[2] = (*params[0]) * (*params[1]);
}
template<typename T>
void intCode<T>::modify3()
{
std::vector<T *> params(1);
setParaMode(params);
*params[0] = input_;
}
template<typename T>
void intCode<T>::modify4()
{
std::vector<T *> params(1);
setParaMode(params);
lastOut_ = *params[0];
}
template<typename T>
void intCode<T>::modify5()
{
std::vector<T *> params(2);
setParaMode(params);
if (*params[0] != 0) { pos_ = *params[1]; }
else { pos_ += 3; }
}
template<typename T>
void intCode<T>::modify6()
{
std::vector<T *> params(2);
setParaMode(params);
if (*params[0] == 0) { pos_ = *params[1]; }
else { pos_ += 3; }
}
template<typename T>
void intCode<T>::modify7()
{
std::vector<T *> params(3);
setParaMode(params);
if (*params[0] < *params[1]) { *params[2] = 1; } else { *params[2] = 0; }
}
template<typename T>
void intCode<T>::modify8()
{
std::vector<T *> params(3);
setParaMode(params);
if (*params[0] == *params[1]) { *params[2] = 1; } else { *params[2] = 0; }
}
template<typename T>
void intCode<T>::modify9()
{
std::vector<T *> params(1);
setParaMode(params);
relBase_ += *params[0];
}
template<typename T>
void intCode<T>::getParameterMode() {
// 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
// -------------------------
paraMode_.resize(0);
std::string xs = std::to_string(code_[pos_]);
if (xs.size() > 2) {
std::string ops = xs.substr(xs.size()-2);
paraMode_.push_back(std::stoi(ops));
for (int i = xs.size()-3; i >= 0; i--) {
paraMode_.push_back(xs[i]-'0');
}
} else {
paraMode_.push_back(code_[pos_]);
}
}
template<typename T>
bool intCode<T>::runIntCode(const std::vector<T> & in) {
//
// start gives starting position in int code (default = 0).
// return true IFF program was halted (opcode 99), false otherwise
// -----------------
size_t step = 0;
while (pos_ < code_.size()) {
getParameterMode();
int opcode = paraMode_[0];
if (opcode == 1 || opcode == 2 || opcode == 7 || opcode == 8) {
step = 4;
paraMode_.resize(step);
} else if (opcode == 3 || opcode == 4 || opcode == 9) {
step = 2;
paraMode_.resize(step);
} else if (opcode == 5 || opcode == 6) {
step = 3;
paraMode_.resize(step);
}
if (opcode == 1) { // ALTERNATIVE: Expression templates
modify1();
} else if (opcode == 2) {
modify2();
} else if (opcode == 3) {
inputCount_++;
if (inputCount_ <= in.size()) {
input_ = in[inputCount_-1];
} else {
std::cout << " Too few input arguments provided, type ";
std::cout << "Input here: ";
std::cin >> input_;
}
modify3();
} else if (opcode == 4) {
modify4();
std::cout << lastOut_ << "\n";
if (stopAtOutput_) {
inputCount_ = 0;
pos_ += step;
return false;
}
} else if (opcode == 5) {
modify5();
} else if (opcode == 6) {
modify6();
} else if (opcode == 7) {
modify7();
} else if (opcode == 8) {
modify8();
} else if (opcode == 9) {
modify9();
} else if (opcode == 99) {
return true; // program came to an end
}
else {
std::cout << "ERROR: something went wrong - opcode = " << opcode;
std::cout << "(must be in (1, 2, ..., 8, 99))\n";
return false;
}
if (opcode != 5 && opcode != 6) { pos_ += step; }
} // WHILE pos_ < code_.size()
return false;
}
#endif // INTCODE_HPP
#include <fstream>
#include <algorithm>
#include "intCode.hpp"
template<typename T>
void readData(const std::string & data_path, std::vector<T> & 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();
}
}
int main() {
std::string data_path = "in09.txt";
std::vector<long> initCode;
readData(data_path, initCode);
std::vector<int> test{109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99};
std::vector<long> test2{1102,34915192,34915192,7,4,7,99,0};
std::vector<long> test3{104,1125899906842624,99};
std::vector<long> input{1};
intCode<double> IC(initCode);
IC.runIntCode(input);
}
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