Skip to content

Instantly share code, notes, and snippets.

@kiroma
Created December 9, 2019 23:19
Show Gist options
  • Save kiroma/7572c32d0f841d276013a9add09d6675 to your computer and use it in GitHub Desktop.
Save kiroma/7572c32d0f841d276013a9add09d6675 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <exception>
struct Event
{
enum
{
none = 0,
output = 1,
input = 2
}type = none;
long long* var = nullptr;
operator bool()
{
return type != none;
}
};
constexpr size_t pow(size_t a, size_t b)
{
if(b == 0)
{
return 1;
}
size_t res = a;
for(size_t i = 1; i < b; ++i)
{
res *= a;
}
return res;
}
class Intmachine
{
public:
std::vector<long long> memory;
Intmachine(const std::string_view Intcode)
{
std::ifstream ifs(Intcode.data());
for(long i; ifs >> i; ifs.ignore())
{
memory.push_back(i);
}
memory.resize(memory.size() * 128, 0);
}
size_t relBase = 0;
size_t instr_ptr = 0;
long long &getVar(unsigned char param)
{
unsigned char mode = (memory[instr_ptr]/(10*pow(10, param))) % 10;
switch(mode)
{
case 0:
return memory[memory[instr_ptr + param]];
break;
case 1:
return memory[instr_ptr + param];
break;
case 2:
return memory[memory[instr_ptr + param] + relBase];
break;
default:
std::terminate();
}
}
Event step()
{
switch(memory[instr_ptr]%100)
{
case 1:
getVar(3) = getVar(1) + getVar(2);
instr_ptr += 4;
break;
case 2:
getVar(3) = getVar(1) * getVar(2);
instr_ptr += 4;
break;
case 3:
{
Event e{Event::input, &getVar(1)};
instr_ptr += 2;
return e;
}
case 4:
{
Event e{Event::output, &getVar(1)};
instr_ptr += 2;
return e;
}
case 5:
if(getVar(1))
{
instr_ptr = getVar(2);
break;
}
instr_ptr += 3;
break;
case 6:
if(!getVar(1))
{
instr_ptr = getVar(2);
break;
}
instr_ptr += 3;
break;
case 7:
getVar(3) = getVar(1) < getVar(2);
instr_ptr += 4;
break;
case 8:
getVar(3) = getVar(1) == getVar(2);
instr_ptr += 4;
break;
case 9:
relBase += getVar(1);
instr_ptr += 2;
break;
default:
std::cerr << "Unknown opcode " << memory[instr_ptr] << '\n';
std::terminate();
break;
}
return Event();
}
Event run()
{
while(memory[instr_ptr] != 99)
{
Event e = step();
if(e.type)
{
return e;
}
}
return Event();
}
};
int main()
{
Intmachine machine("input.txt");
while(Event e = machine.run())
{
if(e.type == Event::input)
{
*e.var = 2;
}
else
{
std::cout << *e.var << '\n';
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment