Add solution for 2016 Day 25

This commit is contained in:
Thraix committed 2026-09-04 20:54:17 +02:00
1 parent 551df7ffb2
commit a56cc80169
1 file changed
+173 -7
+173 -7
View File
@@ -2,30 +2,196 @@
namespace y2016::day25 namespace y2016::day25
{ {
REGISTER_DAY(2016, Day25, std::vector<int>, int); enum class Operator
{
Cpy,
Inc,
Dec,
Jnz,
Out,
};
REGISTER_TEST_EXAMPLE(2016, Day25, ExampleInput, 1, 0); struct Instruction
REGISTER_TEST(2016, Day25, Input, 1, 0); {
REGISTER_TEST_EXAMPLE(2016, Day25, ExampleInput, 2, 0); Operator op;
std::variant<char, int> arg1;
std::variant<char, int> arg2;
};
REGISTER_DAY(2016, Day25, std::vector<Instruction>, int);
REGISTER_TEST(2016, Day25, Input, 1, 182);
REGISTER_TEST(2016, Day25, Input, 2, 0); REGISTER_TEST(2016, Day25, Input, 2, 0);
std::variant<char, int> ReadArg(const std::string& str, int arg)
{
size_t pos = str.find(' ');
int i = 0;
while (i < arg)
{
pos = str.find(' ', pos + 1);
i++;
}
if (str[pos + 1] >= 'a' && str[pos + 1] <= 'd')
return str[pos + 1];
return (int)std::atoi(str.c_str() + pos + 1);
}
READ_INPUT(input) READ_INPUT(input)
{ {
std::vector<int> vec; std::vector<Instruction> vec;
std::string str; std::string str;
while (getline(input, str)) while (getline(input, str))
{ {
Instruction instruction;
if (str[0] == 'c')
{
instruction.op = Operator::Cpy;
instruction.arg1 = ReadArg(str, 0);
instruction.arg2 = ReadArg(str, 1);
}
else if (str[0] == 'i')
{
instruction.op = Operator::Inc;
instruction.arg1 = ReadArg(str, 0);
}
else if (str[0] == 'd')
{
instruction.op = Operator::Dec;
instruction.arg1 = ReadArg(str, 0);
}
else if (str[0] == 'j')
{
instruction.op = Operator::Jnz;
instruction.arg1 = ReadArg(str, 0);
instruction.arg2 = ReadArg(str, 1);
}
else if (str[0] == 'o')
{
instruction.op = Operator::Out;
instruction.arg1 = ReadArg(str, 0);
}
vec.emplace_back(instruction);
} }
return vec; return vec;
} }
void Toggle(Instruction& instruction)
{
switch (instruction.op)
{
case Operator::Cpy:
instruction.op = Operator::Jnz;
break;
case Operator::Inc:
instruction.op = Operator::Dec;
break;
case Operator::Dec:
instruction.op = Operator::Inc;
break;
case Operator::Jnz:
instruction.op = Operator::Cpy;
break;
case Operator::Out:
instruction.op = Operator::Inc;
break;
}
}
bool IsValid(const Instruction& instruction)
{
switch (instruction.op)
{
case Operator::Cpy:
return std::holds_alternative<char>(instruction.arg2);
case Operator::Inc:
return std::holds_alternative<char>(instruction.arg1);
case Operator::Dec:
return std::holds_alternative<char>(instruction.arg1);
case Operator::Jnz:
return true;
case Operator::Out:
return true;
}
return false;
}
int GetRegisterIndex(const std::variant<char, int>& c)
{
return std::get<char>(c) - 'a';
}
int GetValue(const std::vector<int>& registers, const std::variant<char, int>& data)
{
if (std::holds_alternative<int>(data))
return std::get<int>(data);
else
return registers[GetRegisterIndex(data)];
}
bool Run(std::vector<Instruction> instructions, std::vector<int> registers)
{
int count = 0;
for (size_t pc = 0; pc < instructions.size(); pc++)
{
// From analysis of the input, it loops the same output every time we get to pc = 8.
// As such, if we get there, and count is > 0, we know that the signal alternates, since we've already returned
// false if the output to this point is not alternating
if (pc == 8 && count > 0)
return true;
switch (instructions[pc].op)
{
case Operator::Cpy:
{
int number = GetValue(registers, instructions[pc].arg1);
registers[GetRegisterIndex(instructions[pc].arg2)] = number;
break;
}
case Operator::Inc:
{
registers[GetRegisterIndex(instructions[pc].arg1)]++;
break;
}
case Operator::Dec:
{
registers[GetRegisterIndex(instructions[pc].arg1)]--;
break;
}
case Operator::Jnz:
{
int value = GetValue(registers, instructions[pc].arg1);
if (value != 0)
pc += GetValue(registers, instructions[pc].arg2) - 1;
break;
}
case Operator::Out:
{
if (GetValue(registers, instructions[pc].arg1) != count % 2)
return false;
count++;
}
break;
}
}
return false;
}
OUTPUT1(input) OUTPUT1(input)
{ {
return 0; int i = -1;
while (!Run(input, std::vector<int>{++i, 0, 0, 0}))
;
return i;
} }
OUTPUT2(input) OUTPUT2(input)
{ {
return 0; std::cout << " ___ ___" << std::endl;
std::cout << " (o o) (o o)" << std::endl;
std::cout << "( V ) MERRY CHRISTMAS! ( V )" << std::endl;
std::cout << "--m-m----------------------m-m--" << std::endl;
return Run(input, std::vector<int>{12, 0, 0, 0});
} }
} }