Implement day 24 part 2.

This commit is contained in:
2019-12-24 18:45:12 +01:00
parent 3c682b31e9
commit 6211990235

View File

@@ -2,11 +2,15 @@
#include <vector>
#include <algorithm>
#include <set>
#include <numeric>
#include "days.hpp"
namespace {
using field_t = std::array<std::array<bool, 5>, 5>;
constexpr int EDGE = 4;
constexpr int MIDPOINT = 2;
field_t read_input(std::istream &input) {
std::string buffer;
field_t map;
@@ -42,6 +46,105 @@ namespace {
}
}
}
int num_bees(const field_t &field) {
int total = 0;
for (auto &row : field) {
total += std::count(row.begin(), row.end(), true);
}
return total;
}
std::unordered_map<int, field_t> advance(const std::unordered_map<int, field_t> &state) {
const auto dimension_range = std::minmax_element(state.begin(), state.end());
const auto min = dimension_range.first->first - 1;
const auto max = dimension_range.second->first + 1;
std::unordered_map<int, field_t> next_gen;
auto has_bee = [&state](int dimension, int x, int y) {
if (auto it = state.find(dimension); it != state.end()) {
return it->second[y][x];
}
return false;
};
for (int dimension = min; dimension <= max; ++dimension) {
field_t field{};
if (auto it = state.find(dimension); it != state.end()) {
field = it->second;
}
auto get_neighbours = [has_bee,dimension](int x, int y) {
int neighbours = 0;
// Cell above
if (y == 0) {
neighbours += has_bee(dimension + 1, MIDPOINT, 1);
} else if (y == 3 && x == MIDPOINT) {
for (int sx = 0; sx < 5; ++sx) {
neighbours += has_bee(dimension - 1, sx, EDGE);
}
} else {
neighbours += has_bee(dimension, x, y - 1);
}
// Cell below
if (y == EDGE) {
neighbours += has_bee(dimension + 1, MIDPOINT, 3);
} else if (y == 1 && x == MIDPOINT) {
for (int sx = 0; sx < 5; ++sx) {
neighbours += has_bee(dimension - 1, sx, 0);
}
} else {
neighbours += has_bee(dimension, x, y + 1);
}
// Cell left
if (x == 0) {
neighbours += has_bee(dimension + 1, 1, 2);
} else if (x == 3 && y == MIDPOINT) {
for (int sy = 0; sy < 5; ++sy) {
neighbours += has_bee(dimension - 1, EDGE, sy);
}
} else {
neighbours += has_bee(dimension, x - 1, y);
}
// Cell right
if (x == EDGE) {
neighbours += has_bee(dimension + 1, 3, MIDPOINT);
} else if (x == 1 && y == MIDPOINT) {
for (int sy = 0; sy < 5; ++sy) {
neighbours += has_bee(dimension - 1, 0, sy);
}
} else {
neighbours += has_bee(dimension, x + 1, y);
}
return neighbours;
};
for (int y = 0; y < 5; ++y) {
for (int x = 0; x < 5; ++x) {
auto neighbours = get_neighbours(x, y);
field[y][x] = neighbours == 1 || (neighbours == 2 && !field[y][x]);
}
}
// Don't evolve the midpoint.
field[2][2] = false;
if (num_bees(field) || (dimension != min && dimension != max)) {
next_gen[dimension] = field;
}
}
return next_gen;
}
}
void aoc2019::day24_part1(std::istream &input, std::ostream &output) {
@@ -70,5 +173,16 @@ void aoc2019::day24_part1(std::istream &input, std::ostream &output) {
}
void aoc2019::day24_part2(std::istream &input, std::ostream &output) {
output << "Not implemented\n";
std::unordered_map<int, field_t> fields;
fields[0] = read_input(input);
for (int gen = 0; gen < 200; ++gen) {
fields = advance(fields);
}
int total = std::accumulate(fields.begin(), fields.end(), 0, [](auto cur, const auto &it) {
return cur + num_bees(it.second);
});
output << total << std::endl;
}