Files
AdventOfCode/src/2016/Day22.cpp
T
2026-09-04 18:37:13 +02:00

137 lines
3.0 KiB
C++

#include "common/aoc.h"
namespace y2016::day22
{
struct Fs
{
int used;
int avail;
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<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)
{
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)
{
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);
}
}