135 lines
2.8 KiB
C++
135 lines
2.8 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
enum Command {
|
|
NOOP = 1,
|
|
ADDX,
|
|
};
|
|
|
|
Command ParseCommand(const std::string &str) {
|
|
if(str.size() < 4)
|
|
return Command::NOOP;
|
|
|
|
std::string head = str.substr(0, 4);
|
|
if(head == "noop")
|
|
return Command::NOOP;
|
|
else if(head == "addx")
|
|
return Command::ADDX;
|
|
|
|
std::cerr << "Missing command type \"" << head << "\"." << std::endl;
|
|
exit(-1);
|
|
}
|
|
|
|
void IncrementCycleCount(long &cycle, const Command &command);
|
|
long Report(const long &cycle, const long &x);
|
|
void ApplyAction(const std::pair<Command, std::string> &command, long &x);
|
|
|
|
int main()
|
|
{
|
|
std::ifstream ifs("data.txt");
|
|
if(!ifs.is_open())
|
|
{
|
|
std::cerr << "Missing data.txt." << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
unsigned long total = 0;
|
|
unsigned long total_pt2 = 0;
|
|
|
|
std::vector<std::pair<Command, std::string> > commands;
|
|
for(std::string line; std::getline(ifs, line); )
|
|
{
|
|
if(line == "")
|
|
continue;
|
|
|
|
auto cmd = ParseCommand(line);
|
|
if(cmd == Command::NOOP)
|
|
commands.push_back({cmd, ""});
|
|
else
|
|
commands.push_back({cmd, line.substr(5)});
|
|
}
|
|
|
|
long cycle = 1;
|
|
long x = 1;
|
|
for(const auto &command : commands)
|
|
{
|
|
// Step 1: Increase cycle count of command to see if we would have reported
|
|
IncrementCycleCount(cycle, command.first);
|
|
|
|
// Step 2: Report, if needed:
|
|
total += Report(cycle, x);
|
|
|
|
// Step 3: Perform command action:
|
|
ApplyAction(command, x);
|
|
}
|
|
|
|
while(cycle <= 220)
|
|
{
|
|
IncrementCycleCount(cycle, Command::NOOP);
|
|
total += Report(cycle, x);
|
|
}
|
|
|
|
std::cout << "Ended on cycle #" << cycle << ", value of x: " << x << std::endl;
|
|
|
|
std::cout << " Total: " << total << std::endl;
|
|
std::cout << "PT2 Total: " << total_pt2 << std::endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void IncrementCycleCount(long &cycle, const Command &command)
|
|
{
|
|
switch(command)
|
|
{
|
|
case Command::NOOP:
|
|
cycle++;
|
|
break;
|
|
case Command::ADDX:
|
|
cycle += 2;
|
|
break;
|
|
default:
|
|
std::cerr << "Missing ability to parse command type." << std::endl;
|
|
exit(-1);
|
|
break;
|
|
};
|
|
}
|
|
|
|
long Report(const long &cycle, const long &x)
|
|
{
|
|
static long last_reported_cycle = -20;
|
|
auto next_cycle = last_reported_cycle + 40;
|
|
if(cycle > next_cycle)
|
|
{
|
|
std::cout << "Cycle #" << next_cycle << ": "
|
|
<< next_cycle << " * " << x << " = "
|
|
<< next_cycle * x << std::endl;
|
|
last_reported_cycle += 40;
|
|
|
|
return next_cycle * x;
|
|
}
|
|
return 0; // no change
|
|
}
|
|
|
|
void ApplyAction(const std::pair<Command, std::string> &command, long &x)
|
|
{
|
|
switch(command.first)
|
|
{
|
|
case Command::NOOP:
|
|
// std::cout << "NOOP" << std::endl;
|
|
// noop
|
|
break;
|
|
case Command::ADDX:
|
|
// std::cout << "ADDX " << command.second << ": x goes from " << x << " to ";
|
|
x += std::atoi(command.second.c_str());
|
|
// std::cout << x << std::endl;
|
|
break;
|
|
default:
|
|
std::cerr << "Missing ability to parse command type." << std::endl;
|
|
exit(-1);
|
|
break;
|
|
};
|
|
}
|