49 lines
1.1 KiB
C++
49 lines
1.1 KiB
C++
|
#ifndef INTCODE_HPP_
|
||
|
#define INTCODE_HPP_
|
||
|
|
||
|
#include <istream>
|
||
|
#include <cstddef>
|
||
|
#include <vector>
|
||
|
#include <cstdint>
|
||
|
#include <variant>
|
||
|
#include <unordered_map>
|
||
|
|
||
|
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||
|
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||
|
|
||
|
struct BadInstruction : public std::exception {
|
||
|
std::int64_t instruction;
|
||
|
explicit BadInstruction(std::int64_t instruction) : instruction{instruction} {}
|
||
|
const char* what() const noexcept override {
|
||
|
return "bad instruction";
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct Input {
|
||
|
std::int64_t& pos;
|
||
|
};
|
||
|
|
||
|
struct Output {
|
||
|
std::int64_t val;
|
||
|
};
|
||
|
|
||
|
struct Halt {};
|
||
|
|
||
|
class intcode {
|
||
|
std::vector<std::int64_t> rom_;
|
||
|
std::unordered_map<std::size_t, std::int64_t> ram_;
|
||
|
std::size_t pc_;
|
||
|
std::size_t base_;
|
||
|
|
||
|
auto ref(std::int64_t instruction, std::int64_t p, std::size_t offset) -> std::int64_t&;
|
||
|
|
||
|
public:
|
||
|
intcode();
|
||
|
intcode(std::vector<std::int64_t> ram);
|
||
|
auto step() -> std::variant<Input, Output, Halt>;
|
||
|
auto at(std::size_t) -> std::int64_t&;
|
||
|
};
|
||
|
|
||
|
auto parse_stream(std::istream& in) -> std::vector<std::int64_t>;
|
||
|
|
||
|
#endif // INTCODE_HPP_
|