Compare commits

..
2 Commits
Author SHA1 Message Date
Thraix edc2fd0b6c Add solution for 2016 Day 23 2026-09-04 18:37:21 +02:00
Thraix bec8be80a3 Add solution for 2016 Day 22 2026-09-04 18:37:13 +02:00
6 changed files with 322 additions and 16 deletions

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
root@ebhq-gridcenter# df -h
Filesystem Size Used Avail Use%
/dev/grid/node-x0-y0 10T 8T 2T 80%
/dev/grid/node-x0-y1 11T 6T 5T 54%
/dev/grid/node-x0-y2 32T 28T 4T 87%
/dev/grid/node-x1-y0 9T 7T 2T 77%
/dev/grid/node-x1-y1 8T 0T 8T 0%
/dev/grid/node-x1-y2 11T 7T 4T 63%
/dev/grid/node-x2-y0 10T 6T 4T 60%
/dev/grid/node-x2-y1 9T 8T 1T 88%
/dev/grid/node-x2-y2 9T 6T 3T 66%
+7
View File
@@ -0,0 +1,7 @@
cpy 2 a
tgl a
tgl a
tgl a
cpy 1 a
dec a
dec a
+113 -8
View File
@@ -2,30 +2,135 @@
namespace y2016::day22
{
REGISTER_DAY(2016, Day22, std::vector<int>, int);
struct Fs
{
int used;
int avail;
REGISTER_TEST_EXAMPLE(2016, Day22, ExampleInput, 1, 0);
REGISTER_TEST(2016, Day22, Input, 1, 0);
REGISTER_TEST_EXAMPLE(2016, Day22, ExampleInput, 2, 0);
REGISTER_TEST(2016, Day22, Input, 2, 0);
bool operator==(const Fs& other) const
{
return used == other.used && avail == other.avail;
}
};
REGISTER_DAY(2016, Day22, Array2D<Fs>, int);
REGISTER_TEST_EXAMPLE(2016, Day22, ExampleInput, 1, 7);
REGISTER_TEST(2016, Day22, Input, 1, 1024);
REGISTER_TEST_EXAMPLE(2016, Day22, ExampleInput, 2, 7);
REGISTER_TEST(2016, Day22, Input, 2, 230);
READ_INPUT(input)
{
std::vector<int> vec;
std::vector<std::pair<std::pair<int, int>, Fs>> fss;
Array2D<Fs> vec{};
std::string str;
getline(input, str);
getline(input, str);
int maxX = 0;
int maxY = 0;
while (getline(input, str))
{
// /dev/grid/node-x0-y0 91T 71T 20T 78%
Fs fs;
std::stringstream ss{str};
int dummy;
int x;
int y;
ss >> "/dev/grid/node-x" >> x >> "-y" >> y >> dummy >> "T" >> fs.used >> "T" >> fs.avail >> "T";
fss.emplace_back(std::pair{std::pair{x, y}, fs});
maxX = std::max(maxX, x);
maxY = std::max(maxY, y);
}
vec = Array2D<Fs>{maxX + 1, maxY + 1};
for (const auto& [pos, fs] : fss)
{
vec.Set(pos.first, pos.second, fs);
}
return vec;
}
struct State
{
Index2D goal;
Index2D empty;
bool operator<(const State& other) const
{
if (goal != other.goal)
return goal < other.goal;
return empty < other.empty;
}
friend std::ostream& operator<<(std::ostream& os, const State& state)
{
return os << state.goal << " " << state.empty;
}
};
std::vector<std::pair<int, State>> Branch(const Array2D<Fs>& initial, const State& state)
{
std::vector<std::pair<int, State>> states{};
Fs emptyFs = initial.Get(state.empty);
std::vector<Index2D> neighbors = initial.GetNeighbors(state.empty, false);
for (const auto& neighbor : neighbors)
{
if (initial.Get(neighbor).used < 400)
{
State newState = state;
if (neighbor == state.goal)
newState.goal = state.empty;
newState.empty = neighbor;
states.emplace_back(1, newState);
}
}
return states;
}
bool Goal(const Array2D<Fs>& initial, const State& state)
{
return state.goal == Index2D{0, 0};
}
int Heuristic(const Array2D<Fs>& initial, const State& state)
{
return state.goal.x + state.goal.y;
}
OUTPUT1(input)
{
return 0;
int count = 0;
for (const auto& val : input)
{
if (val.used == 0)
continue;
for (const auto& val2 : input)
{
if (val == val2)
continue;
if (val.used <= val2.avail)
{
count++;
}
}
}
return count;
}
OUTPUT2(input)
{
return 0;
State state;
state.goal = Index2D{input.width - 1, 0};
for (int i = 0; i < input.height; i++)
{
for (int j = 0; j < input.width; j++)
{
if (input.Get(j, i).used == 0)
{
state.empty = Index2D{j, i};
}
}
}
return Helper::AStar(input, state, Heuristic, Branch, Goal);
}
}
+175 -8
View File
@@ -2,30 +2,197 @@
namespace y2016::day23
{
REGISTER_DAY(2016, Day23, std::vector<int>, int);
enum class Operator
{
Cpy,
Inc,
Dec,
Jnz,
Tgl
};
REGISTER_TEST_EXAMPLE(2016, Day23, ExampleInput, 1, 0);
REGISTER_TEST(2016, Day23, Input, 1, 0);
REGISTER_TEST_EXAMPLE(2016, Day23, ExampleInput, 2, 0);
REGISTER_TEST(2016, Day23, Input, 2, 0);
struct Instruction
{
Operator op;
std::variant<char, int> arg1;
std::variant<char, int> arg2;
};
REGISTER_DAY(2016, Day23, std::vector<Instruction>, int);
REGISTER_TEST(2016, Day23, Input, 1, 11415);
REGISTER_TEST(2016, Day23, Input, 2, 479007975);
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)
{
std::vector<int> vec;
std::vector<Instruction> vec;
std::string 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] == 't')
{
instruction.op = Operator::Tgl;
instruction.arg1 = ReadArg(str, 0);
}
vec.emplace_back(instruction);
}
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::Tgl:
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::Tgl:
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)];
}
int Run(std::vector<Instruction> instructions, std::vector<int> registers)
{
int i = 0;
for (size_t pc = 0; pc < instructions.size(); pc++)
{
i++;
if (!IsValid(instructions[pc]))
continue;
// The input program I got does a multiplication (a = b * d). So instead of using the ++, -- operators, calculate
// it directly and set the registers to expected value after the operation is done.
// Other inputs might have different pc position, and multiply different registers.
if (pc == 4)
{
registers[0] = registers[1] * registers[3];
registers[3] = 0;
registers[2] = registers[1];
pc = 9;
}
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::Tgl:
{
int offset = registers[GetRegisterIndex(instructions[pc].arg1)];
if (pc + offset >= 0 && pc + offset < instructions.size())
Toggle(instructions[pc + offset]);
}
break;
}
}
return registers[0];
}
OUTPUT1(input)
{
return 0;
return Run(input, std::vector<int>{7, 0, 0, 0});
}
OUTPUT2(input)
{
return 0;
return Run(input, std::vector<int>{12, 0, 0, 0});
}
}
+5
View File
@@ -500,6 +500,11 @@ struct Array2D
return ConstIterator{*this, Index2D{0, height}};
}
bool operator<(const Array2D<T>& other) const
{
return array2D < other.array2D;
}
friend std::ostream& operator<<(std::ostream& os, const Array2D& array2D)
{
for (int y = 0; y < array2D.height; y++)
+11
View File
@@ -11,6 +11,7 @@
#include <map>
#include <numeric>
#include <set>
#include <variant>
#include <vector>
#include "Array2D.h"
@@ -33,6 +34,9 @@ static std::ostream& operator<<(std::ostream& stream, const std::map<T, S>& cont
template <typename T, typename S>
static std::ostream& operator<<(std::ostream& stream, const std::pair<T, S>& pair);
template <typename Arg1, typename Arg2, typename... Args>
static std::ostream& operator<<(std::ostream& stream, const std::variant<Arg1, Arg2, Args...>& variant);
struct Helper
{
struct ScopedTraceErrorDisabler
@@ -639,3 +643,10 @@ static std::ostream& operator<<(std::ostream& stream, const std::pair<T, S>& pai
{
return stream << "(" << pair.first << ", " << pair.second << ")";
}
template <typename Arg1, typename Arg2, typename... Args>
static std::ostream& operator<<(std::ostream& stream, const std::variant<Arg1, Arg2, Args...>& variant)
{
std::visit([&stream](const auto& value) { stream << value; }, variant);
return stream;
}