From 2255db3981a2a65ef433d5da6f0ed0b4cb394db4 Mon Sep 17 00:00:00 2001 From: Gnarwhal Date: Wed, 16 Dec 2020 22:46:56 -0800 Subject: [PATCH] Completed day 17 --- 2020/days/day17.cpp | 163 ++++++++++++++++++++++++++++++++++++++++ 2020/inputs/day17.input | 8 ++ 2 files changed, 171 insertions(+) create mode 100644 2020/days/day17.cpp create mode 100644 2020/inputs/day17.input diff --git a/2020/days/day17.cpp b/2020/days/day17.cpp new file mode 100644 index 0000000..a016751 --- /dev/null +++ b/2020/days/day17.cpp @@ -0,0 +1,163 @@ +/******************************************************************************* + * + * Copyright (c) 2020 Gnarwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "../misc/types.hpp" +#include "../misc/print.hpp" + +constexpr auto CYCLES = 6; +constexpr auto BUFFER = CYCLES + 1; + +auto neighbor3d_count(const auto & pocket, i32 x, i32 y, i32 z) -> usize { + auto count = usize(0); + for (auto i = i32(-1); i < 2; ++i) { + for (auto j = i32(-1); j < 2; ++j) { + for (auto k = i32(-1); k < 2; ++k) { + count += (i != 0 || j != 0 || k != 0) && pocket[x + i][y + j][z + k]; + } + } + } + return count; +} + +auto neighbor4d_count(const auto & pocket, i32 w, i32 x, i32 y, i32 z) -> usize { + auto count = usize(0); + for (auto i = i32(-1); i < 2; ++i) { + for (auto j = i32(-1); j < 2; ++j) { + for (auto k = i32(-1); k < 2; ++k) { + for (auto l = i32(-1); l < 2; ++l) { + count += (i != 0 || j != 0 || k != 0 || l != 0) && pocket[w + l][x + i][y + j][z + k]; + } + } + } + } + return count; +} + +auto day17() -> void { + auto pocket = std::vector>>>(); + { + auto lines = std::vector(); + auto line = std::string(); + auto file = std::ifstream("inputs/day17.input"); + while (getline(file, line)) { + lines.push_back(line); + } + + + pocket = std::vector>>>(BUFFER * 2 + 1); + for (auto w = usize(0); w < pocket.size(); ++w) { + pocket[w] = std::vector>>(lines[0].size() + BUFFER * 2); + for (auto i = usize(0); i < pocket[0].size(); ++i) { + auto vec = std::vector>(lines.size() + BUFFER * 2); + for (auto j = usize(0); j < vec.size(); ++j) { + vec[j] = std::vector(BUFFER * 2 + 1); + if (w == BUFFER && i >= BUFFER && i < BUFFER + lines[0].size() && j >= BUFFER && j < BUFFER + lines.size()) { + vec[j][BUFFER] = lines[j - BUFFER][i - BUFFER] == '#'; + } + } + pocket[w][i] = std::move(vec); + } + } + } + + { + auto pockets = std::array>>, 2>{ pocket[BUFFER], pocket[BUFFER] }; + auto bit = false; + for (auto i = usize(0); i < CYCLES; ++i) { + auto & read = pockets[bit]; + auto & write = pockets[bit = !bit]; + for (auto x = i32(1); x < read.size() - 1; ++x) { + for (auto y = i32(1); y < read[0].size() - 1; ++y) { + for (auto z = i32(1); z < read[0][0].size() - 1; ++z) { + auto neighbors = neighbor3d_count(read, x, y, z); + if (read[x][y][z] && (neighbors < 2 || neighbors > 3)) { + write[x][y][z] = false; + } else if (!read[x][y][z] && neighbors == 3) { + write[x][y][z] = true; + } else { + write[x][y][z] = read[x][y][z]; + } + } + } + } + } + + auto & pocket = pockets[bit]; + auto count = usize(0); + for (auto i = usize(0); i < pocket.size(); ++i) { + for (auto j = usize(0); j < pocket[0].size(); ++j) { + for (auto k = usize(0); k < pocket[0][0].size(); ++k) { + count += pocket[i][j][k]; + } + } + } + print(count); + } + + { + auto pockets = std::array>>>, 2>{ pocket, pocket }; + auto bit = false; + for (auto i = usize(0); i < CYCLES; ++i) { + auto & read = pockets[bit]; + auto & write = pockets[bit = !bit]; + for (auto w = i32(1); w < read.size() - 1; ++w) { + for (auto x = i32(1); x < read[0].size() - 1; ++x) { + for (auto y = i32(1); y < read[0][0].size() - 1; ++y) { + for (auto z = i32(1); z < read[0][0][0].size() - 1; ++z) { + auto neighbors = neighbor4d_count(read, w, x, y, z); + if (read[w][x][y][z] && (neighbors < 2 || neighbors > 3)) { + write[w][x][y][z] = false; + } else if (!read[w][x][y][z] && neighbors == 3) { + write[w][x][y][z] = true; + } else { + write[w][x][y][z] = read[w][x][y][z]; + } + } + } + } + } + } + + auto & pocket = pockets[bit]; + auto count = usize(0); + for (auto i = usize(0); i < pocket.size(); ++i) { + for (auto j = usize(0); j < pocket[0].size(); ++j) { + for (auto k = usize(0); k < pocket[0][0].size(); ++k) { + for (auto l = usize(0); l < pocket[0][0][0].size(); ++l) { + count += pocket[i][j][k][l]; + } + } + } + } + print(count); + } +} diff --git a/2020/inputs/day17.input b/2020/inputs/day17.input new file mode 100644 index 0000000..9883294 --- /dev/null +++ b/2020/inputs/day17.input @@ -0,0 +1,8 @@ +###...#. +.##.#### +.####.## +###.###. +.##.#### +#.##..#. +##.####. +.####.#.