Advent of Code 2022 - 2nd attempt in c++
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
2.0 KiB

2 years ago
#include <iostream>
#include <vector>
using namespace std;
enum Opcode {
NOOP,
ADDX
};
struct Instr {
Opcode op;
int arg;
};
unsigned instr_cycles[] = {
1, // NOOP
2 // ADDX
};
typedef vector<Instr> Input;
Input parse()
{
Input data;
for (string line; getline(cin, line);) {
Instr instr;
string op = line.substr(0, 5);
if (op == "noop") {
instr.op = NOOP;
} else if (op == "addx ") {
instr.op = ADDX;
instr.arg = stoi(line.substr(5));
}
data.push_back(instr);
}
return data;
}
class Cpu {
const vector<Instr> *prog;
vector<Instr>::const_iterator cur;
unsigned cur_cycles = 0;
bool run = true;
public:
unsigned cycle = 1;
int X = 1;
Cpu(const vector<Instr> *prog) {
this->prog = prog;
this->cur = prog->begin();
}
void tick();
bool running() { return run; }
};
void Cpu::tick()
{
if (!run) return;
// Fetch next instruction
if (!cur_cycles) {
cur_cycles = instr_cycles[cur->op];
}
// Execute instruction when done
if (!--cur_cycles) {
switch (cur->op) {
case NOOP:
break;
case ADDX:
this->X += cur->arg;
break;
}
cur++;
if (cur >= prog->end()) run = false;
}
cycle++;
}
unsigned p1(const Input &input)
{
unsigned sum = 0;
Cpu cpu(&input);
while (cpu.running()) {
if ((cpu.cycle + 20) % 40 == 0) sum += cpu.cycle * cpu.X;
cpu.tick();
}
return sum;
}
#define WIDTH 40
2 years ago
void p2(const Input &input)
{
Cpu cpu(&input);
while (cpu.running()) {
// Calculate current CRT line
int X = cpu.cycle % WIDTH;
if (X == 0) X += WIDTH;
2 years ago
// Draw pixel
if (cpu.X <= X && X <= cpu.X + 2) cout << '#';
else cout << '.';
if (X == WIDTH) cout << endl;
2 years ago
cpu.tick();
}
}
int main()
{
auto input = parse();
cout << p1(input) << endl;
p2(input);
}