Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Intcode_computer
- {
- public:
- explicit Intcode_computer(const std::vector<int64_t>& mem)
- :memory{mem}
- {
- }
- bool process_next_instruction()
- {
- auto instruction = to_instruction(get_opcode());
- auto parameters = parse_parameters(get_parametercode(), instruction);
- return process_instruction(instruction, parameters);
- }
- void set_userinput(int u_i)
- {
- userinput = u_i;
- }
- private:
- enum Instruction
- {
- add = 1,
- mult = 2,
- write_userinput = 3,
- output = 4,
- jump_if_true = 5,
- jump_if_false = 6,
- less_than = 7,
- equals = 8,
- adjust_relative_base = 9,
- exit = 99
- };
- enum Parametermode
- {
- position,
- immediate,
- relative
- };
- Instruction to_instruction(int opcode)
- {
- return static_cast<Instruction>(opcode);
- }
- std::vector<int64_t> parse_parameters(int parametercode, const Instruction& instruction)
- {
- std::vector<int64_t> p;
- switch (instruction)
- {
- // cases where three parameters are used
- case add:
- case mult:
- case less_than:
- case equals:
- {
- for (int i = 0; i < 3; ++i)
- {
- switch (parametercode % 10)
- {
- case position:
- {
- p.push_back(memory[instruction_ptr + i + 1]);
- parametercode /= 10;
- break;
- }
- case immediate:
- {
- p.push_back(instruction_ptr + i + 1);
- parametercode /= 10;
- break;
- }
- case relative:
- {
- p.push_back(memory[instruction_ptr + i + 1] + relative_base);
- parametercode /= 10;
- break;
- }
- }
- }
- break;
- }
- //cases where two parameters are used
- case jump_if_true:
- case jump_if_false:
- {
- for (int i = 0; i < 2; ++i)
- {
- switch (parametercode % 10)
- {
- case position:
- {
- p.push_back(memory[instruction_ptr + i + 1]);
- parametercode /= 10;
- break;
- }
- case immediate:
- {
- p.push_back(instruction_ptr + i + 1);
- parametercode /= 10;
- break;
- }
- case relative:
- {
- p.push_back(memory[instruction_ptr + i + 1] + relative_base);
- parametercode /= 10;
- break;
- }
- }
- }
- break;
- }
- // cases where one parameter is used
- case write_userinput:
- case output:
- case adjust_relative_base:
- {
- switch (parametercode % 10)
- {
- case position:
- {
- p.push_back(memory[instruction_ptr + 1]);
- break;
- }
- case immediate:
- {
- p.push_back(instruction_ptr + 1);
- break;
- }
- case relative:
- {
- p.push_back(memory[instruction_ptr + 1] + relative_base);
- break;
- }
- }
- }
- // handle exit
- case exit:
- {
- break;
- }
- default:
- {
- std::cout << "error has occured\n";
- break;
- }
- }
- return p;
- }
- // return false if exit instruction is encountered
- bool process_instruction(Instruction instruction, const std::vector<int64_t>& p)
- {
- auto& m = memory;
- switch (instruction)
- {
- case add:
- {
- m[p[2]] = m[p[1]] + m[p[0]];
- instruction_ptr += 4;
- return true;
- }
- case mult:
- {
- m[p[2]] = m[p[1]] * m[p[0]];
- instruction_ptr += 4;
- return true;
- }
- case write_userinput:
- {
- m[p[0]] = userinput;
- instruction_ptr += 2;
- return true;
- }
- case output:
- {
- std::cout << m[p[0]] << std::endl;
- instruction_ptr += 2;
- return true;
- }
- case jump_if_true:
- {
- if (m[p[0]] != 0)
- {
- instruction_ptr = m[p[1]];
- }
- else
- {
- instruction_ptr += 3;
- }
- return true;
- }
- case jump_if_false:
- {
- if (m[p[0]] == 0)
- {
- instruction_ptr = m[p[1]];
- }
- else
- {
- instruction_ptr += 3;
- }
- return true;
- }
- case less_than:
- {
- if (m[p[0]] < m[p[1]])
- {
- m[p[2]] = 1;
- }
- else
- {
- m[p[2]] = 0;
- }
- instruction_ptr += 4;
- return true;
- }
- case equals:
- {
- if (m[p[0]] == m[p[1]])
- {
- m[p[2]] = 1;
- }
- else
- {
- m[p[2]] = 0;
- }
- instruction_ptr += 4;
- return true;
- }
- case adjust_relative_base:
- {
- relative_base += m[p[0]];
- instruction_ptr += 2;
- return true;
- }
- case exit:
- {
- return false;
- }
- }
- }
- int get_opcode()
- {
- return memory[instruction_ptr] % 100;
- }
- int get_parametercode()
- {
- return memory[instruction_ptr] / 100;
- }
- int relative_base = 0;
- int userinput = -1;
- int instruction_ptr = 0;
- std::vector<int64_t> memory;
- };
- int main()
- {
- auto intcode = read_and_parse_input();
- Intcode_computer machine{intcode};
- machine.set_userinput(2);
- while (machine.process_next_instruction());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement