#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, 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, Fs>> fss; Array2D 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{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> Branch(const Array2D& initial, const State& state) { std::vector> states{}; Fs emptyFs = initial.Get(state.empty); std::vector 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& initial, const State& state) { return state.goal == Index2D{0, 0}; } int Heuristic(const Array2D& 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); } }