diff --git a/2019/src/day24.cpp b/2019/src/day24.cpp index efec840..3d69eea 100644 --- a/2019/src/day24.cpp +++ b/2019/src/day24.cpp @@ -2,11 +2,15 @@ #include #include #include +#include #include "days.hpp" namespace { using field_t = std::array, 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 advance(const std::unordered_map &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 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 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; }