diff --git a/2018/puzzle-12-01.cc b/2018/puzzle-12-01.cc new file mode 100644 index 0000000..bbe64b8 --- /dev/null +++ b/2018/puzzle-12-01.cc @@ -0,0 +1,106 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; + +constexpr char plant{'#'}; +constexpr char soil{'.'}; + +unsigned encode(std::string const& s) +{ + UInt result{0}; + for (auto c : s) { + result <<= 1; + result |= (c == plant) ? 1 : 0; + } + return result; +} + +auto main() -> int +{ + std::string line; + std::regex const initial_re{"^initial state: ([#.]+)$"}; + std::regex const map_re{"^([#.]{5}) => ([#.])"}; + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read line.\n"; + return EXIT_FAILURE; + } + std::smatch m; + if (!std::regex_match(line, m, initial_re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + + std::string state{m.str(1)}; + Int state_offset{0}; + state.insert(state.begin(), 3, soil); + state.insert(state.end(), 3, soil); + state_offset -= 3; + + std::vector transitions(32, soil); + while (std::getline(std::cin, line)) { + if (line.empty()) { + continue; + } + + std::smatch m; + if (!std::regex_match(line, m, map_re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + std::cout << line << "\n"; + if (m.str(2) == std::string(1, plant)) { + transitions.at(encode(m.str(1))) = plant; + } + } + + for (unsigned i{0}; i < transitions.size(); ++i) { + std::cout << ((i & 16) ? plant : soil) << ((i & 8) ? plant : soil) << ((i & 4) ? plant : soil) + << ((i & 2) ? plant : soil) << ((i & 1) ? plant : soil) << " => " << transitions[i] + << "\n"; + } + constexpr UInt num_runs{20}; + for (UInt i{0}; i < num_runs; ++i) { + std::cout << std::setw(2) << i << ": " << state << "\n"; + state.insert(state.begin(), 2, soil); + state.insert(state.end(), 2, soil); + state_offset -= 2; + std::string next_state(2, soil); + next_state.reserve(state.size()); + + UInt encoding{encode(state.substr(0, 4))}; + for (UInt p{4}; p < state.size(); ++p) { + encoding <<= 1; + encoding |= state[p] == plant ? 1 : 0; + encoding &= 31; + next_state.push_back(transitions[encoding]); + } + next_state.insert(next_state.end(), 2, soil); + assert(next_state.size() == state.size()); + + state = next_state; + } + std::cout << std::setw(2) << 20 << ": " << state << "\n"; + + Int num_plants{std::count(state.begin(), state.end(), plant)}; + + Int score{0}; + Int offset{state_offset}; + for (auto c : state) { + if (c == plant) { + score += offset; + } + ++offset; + } + std::cout << "Score: " << score << "\n"; + return EXIT_SUCCESS; +} diff --git a/2018/puzzle-12-02.cc b/2018/puzzle-12-02.cc new file mode 100644 index 0000000..82780c3 --- /dev/null +++ b/2018/puzzle-12-02.cc @@ -0,0 +1,108 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; + +constexpr char plant{'#'}; +constexpr char soil{'.'}; + +unsigned encode(std::string const& s) +{ + UInt result{0}; + for (auto c : s) { + result <<= 1; + result |= (c == plant) ? 1 : 0; + } + return result; +} + +auto main() -> int +{ + std::string line; + std::regex const initial_re{"^initial state: ([#.]+)$"}; + std::regex const map_re{"^([#.]{5}) => ([#.])"}; + std::vector state; + + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read line.\n"; + return EXIT_FAILURE; + } + std::smatch m; + if (!std::regex_match(line, m, initial_re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + + Int offset{0}; + for (auto c : m.str(1)) { + if (c == plant) { + state.push_back(offset); + } + ++offset; + } + + std::vector transitions(32, soil); + while (std::getline(std::cin, line)) { + if (line.empty()) { + continue; + } + + std::smatch m; + if (!std::regex_match(line, m, map_re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + + if (m.str(2) == std::string(1, plant)) { + transitions.at(encode(m.str(1))) = plant; + } + } + + constexpr UInt num_runs{50'000'000'000}; + for (UInt i{0}; i < num_runs; ++i) { + if (i % 100'000'000 == 0) { + Int score{ + std::accumulate(state.begin(), state.end(), Int{0}, [](Int a, Int c) { return a + c; })}; + std::cout << std::setw(13) << i << ": " << score << "\n"; + } + Int offset_begin{state.front()}; + Int offset_end{state.back() + 4}; + + std::vector next_state; + next_state.reserve(state.size()); + UInt encoding{0}; + auto it{state.begin()}; + while (offset_begin != offset_end) { + encoding <<= 1; + assert(it == state.end() || *it <= offset_begin); + if (it != state.end() && *it == offset_begin) { + encoding |= 1; + ++it; + } + encoding &= 31; + + if (transitions.at(encoding) == plant) { + next_state.push_back(offset_begin - 2); + } + ++offset_begin; + } + + state = next_state; + } + + Int score{ + std::accumulate(state.begin(), state.end(), Int{0}, [](Int a, Int c) { return a + c; })}; + std::cout << "Score: " << score << "\n"; + return EXIT_SUCCESS; +}