Add 2017 Day 23 puzzles
This commit is contained in:
143
2017/puzzle-23-01.cc
Normal file
143
2017/puzzle-23-01.cc
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using Int = long;
|
||||||
|
using Register = char;
|
||||||
|
using Operand = std::variant<Register, Int, std::monostate>;
|
||||||
|
enum class Opcode { set, sub, mul, jnz };
|
||||||
|
|
||||||
|
auto to_opcode(std::string const& s) -> Opcode
|
||||||
|
{
|
||||||
|
if (s == "set") {
|
||||||
|
return Opcode::set;
|
||||||
|
}
|
||||||
|
if (s == "sub") {
|
||||||
|
return Opcode::sub;
|
||||||
|
}
|
||||||
|
if (s == "mul") {
|
||||||
|
return Opcode::mul;
|
||||||
|
}
|
||||||
|
if (s == "jnz") {
|
||||||
|
return Opcode::jnz;
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto operand(std::string const& s, std::size_t idx) -> std::pair<Operand, std::size_t>
|
||||||
|
{
|
||||||
|
if (idx >= s.size()) {
|
||||||
|
return {std::monostate{}, idx};
|
||||||
|
}
|
||||||
|
if (s[idx] >= 'a' && s[idx] <= 'z') {
|
||||||
|
return {s[idx], idx + 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t end{0};
|
||||||
|
auto v{std::stol(s.substr(idx), &end)};
|
||||||
|
return {v, idx + end};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Instruction
|
||||||
|
{
|
||||||
|
auto opcode() const noexcept -> Opcode { return opcode_; }
|
||||||
|
auto op1() const noexcept -> Operand { return op1_; }
|
||||||
|
auto op2() const noexcept -> Operand { return op2_; }
|
||||||
|
|
||||||
|
static auto instruction(std::string const& s) -> Instruction
|
||||||
|
{
|
||||||
|
auto opcode{to_opcode(s.substr(0, 3))};
|
||||||
|
auto [op1, idx] = operand(s, 4);
|
||||||
|
auto [op2, idx2] = operand(s, idx + 1);
|
||||||
|
return {opcode, op1, op2};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Instruction(Opcode opcode, Operand op1, Operand op2) : opcode_(opcode), op1_(op1), op2_(op2) {}
|
||||||
|
|
||||||
|
Opcode opcode_;
|
||||||
|
Operand op1_;
|
||||||
|
Operand op2_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Instructions = std::vector<Instruction>;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
explicit State(Instructions const& instructions) : instructions_(instructions) {}
|
||||||
|
|
||||||
|
void execute()
|
||||||
|
{
|
||||||
|
while (pc_ >= 0 && pc_ < instructions_.size()) {
|
||||||
|
auto const& instruction{instructions_[pc_]};
|
||||||
|
switch (instruction.opcode()) {
|
||||||
|
case Opcode::sub:
|
||||||
|
set(instruction.op1(), value(instruction.op1()) - value(instruction.op2()));
|
||||||
|
break;
|
||||||
|
case Opcode::jnz:
|
||||||
|
if (value(instruction.op1()) != 0) {
|
||||||
|
pc_ += value(instruction.op2()) - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Opcode::mul:
|
||||||
|
set(instruction.op1(), value(instruction.op1()) * value(instruction.op2()));
|
||||||
|
++mul_count_;
|
||||||
|
break;
|
||||||
|
case Opcode::set:
|
||||||
|
set(instruction.op1(), value(instruction.op2()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
++pc_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Mul executed: " << mul_count_ << " times.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(Register r, Int value) { registers_.insert_or_assign(r, value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void set(Operand const& op, Int value)
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<Register>(op)) {
|
||||||
|
registers_.insert_or_assign(std::get<Register>(op), value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value(Operand const& op) const -> Int
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<Register>(op)) {
|
||||||
|
auto it{registers_.find(std::get<Register>(op))};
|
||||||
|
return it == registers_.end() ? 0 : it->second;
|
||||||
|
}
|
||||||
|
if (std::holds_alternative<Int>(op)) {
|
||||||
|
return std::get<Int>(op);
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
Instructions instructions_;
|
||||||
|
std::map<Register, Int> registers_;
|
||||||
|
Int pc_{0};
|
||||||
|
Int mul_count_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto main() -> int
|
||||||
|
{
|
||||||
|
Instructions instructions;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(std::cin, line) && !line.empty()) {
|
||||||
|
instructions.push_back(Instruction::instruction(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
State cpu{instructions};
|
||||||
|
cpu.execute();
|
||||||
|
return 0;
|
||||||
|
}
|
38
2017/puzzle-23-02.cc
Normal file
38
2017/puzzle-23-02.cc
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using Int = long;
|
||||||
|
|
||||||
|
auto main() -> int
|
||||||
|
{
|
||||||
|
Int a{1};
|
||||||
|
Int b{0};
|
||||||
|
Int c{0};
|
||||||
|
Int d{0};
|
||||||
|
Int e{0};
|
||||||
|
Int f{0};
|
||||||
|
Int g{0};
|
||||||
|
Int h{0};
|
||||||
|
|
||||||
|
b = 107'900;
|
||||||
|
c = b + 17'000;
|
||||||
|
do {
|
||||||
|
d = 2;
|
||||||
|
do {
|
||||||
|
e = b / d;
|
||||||
|
if (d * e == b) {
|
||||||
|
++h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++d;
|
||||||
|
} while (d != b);
|
||||||
|
b += 17;
|
||||||
|
} while (b <= c);
|
||||||
|
|
||||||
|
std::cout << "h = " << h << '\n';
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user