Tidy 2016 day 23 puzzles

This commit is contained in:
2021-12-12 16:24:14 +00:00
parent 29ae944018
commit d14bd5a9c6

View File

@@ -5,11 +5,12 @@
#include <array> #include <array>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <utility>
#include <variant> #include <variant>
#include <vector> #include <vector>
enum class Register { a, b, c, d }; enum class Register { a, b, c, d };
Register to_register(char c) auto to_register(char c) -> Register
{ {
switch (c) { switch (c) {
case 'a': case 'a':
@@ -27,7 +28,7 @@ Register to_register(char c)
enum class Opcode { cpy, inc, dec, jnz, tgl }; enum class Opcode { cpy, inc, dec, jnz, tgl };
Opcode to_opcode(std::string const& s) auto to_opcode(std::string const& s) -> Opcode
{ {
if (s == "cpy") { if (s == "cpy") {
return Opcode::cpy; return Opcode::cpy;
@@ -47,7 +48,7 @@ Opcode to_opcode(std::string const& s)
abort(); abort();
} }
using Int = long; using Int = long; // NOLINT(google-runtime-int)
using Operand = std::variant<Register, Int, std::monostate>; using Operand = std::variant<Register, Int, std::monostate>;
struct Instruction struct Instruction
@@ -57,9 +58,9 @@ struct Instruction
{ {
} }
Opcode opcode() const noexcept { return opcode_; } [[nodiscard]] auto opcode() const noexcept -> Opcode { return opcode_; }
Operand const& op1() const noexcept { return op1_; } [[nodiscard]] auto op1() const noexcept -> Operand const& { return op1_; }
Operand const& op2() const noexcept { return op2_; } [[nodiscard]] auto op2() const noexcept -> Operand const& { return op2_; }
void toggle() void toggle()
{ {
@@ -89,8 +90,10 @@ struct Instruction
{ {
char* end{nullptr}; char* end{nullptr};
auto val{std::strtol(s.data() + idx, &end, 10)}; auto val{
if (end != s.data() + idx) { std::strtol(s.data() + idx, // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
&end, 10)};
if (end != s.data() + idx) { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
op1 = val; op1 = val;
idx = end - s.data(); idx = end - s.data();
} }
@@ -103,9 +106,11 @@ struct Instruction
if (idx < s.size()) { if (idx < s.size()) {
assert(s[idx] == ' '); assert(s[idx] == ' ');
++idx; ++idx;
char* end{0}; char* end{nullptr};
auto val{std::strtol(s.data() + idx, &end, 10)}; auto val{
if (end != s.data() + idx) { std::strtol(s.data() + idx, // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
&end, 10)};
if (end != s.data() + idx) { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
op2 = val; op2 = val;
} }
else { else {
@@ -113,7 +118,7 @@ struct Instruction
} }
} }
return Instruction(opcode, op1, op2); return {opcode, op1, op2};
} }
private: private:
@@ -124,10 +129,19 @@ private:
struct State struct State
{ {
State(std::vector<Instruction> const& instructions) : instructions_(instructions) {} explicit State(std::vector<Instruction> instructions) : instructions_(std::move(instructions)) {}
auto reg(Register r) const noexcept -> Int { return registers_[static_cast<unsigned>(r)]; } [[nodiscard]] auto reg(Register r) const noexcept -> Int
void reg(Register r, Int v) noexcept { registers_[static_cast<unsigned>(r)] = v; } {
return registers_
[static_cast<unsigned>( // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
r)];
}
void reg(Register r, Int v) noexcept
{
registers_[static_cast<unsigned>( // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
r)] = v;
}
void execute() void execute()
{ {
@@ -161,10 +175,12 @@ struct State
} }
private: private:
Int value(Operand const& o) auto value(Operand const& o) -> Int
{ {
if (std::holds_alternative<Register>(o)) { if (std::holds_alternative<Register>(o)) {
return registers_[static_cast<unsigned>(std::get<Register>(o))]; return registers_
[static_cast<unsigned>( // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
std::get<Register>(o))];
} }
if (std::holds_alternative<Int>(o)) { if (std::holds_alternative<Int>(o)) {
return std::get<Int>(o); return std::get<Int>(o);
@@ -175,7 +191,9 @@ private:
void set(Operand const& dest, Int value) void set(Operand const& dest, Int value)
{ {
if (std::holds_alternative<Register>(dest)) { if (std::holds_alternative<Register>(dest)) {
registers_[static_cast<unsigned>(std::get<Register>(dest))] = value; registers_[// NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
static_cast<unsigned>(std::get<Register>(dest))] =
value;
} }
} }