From fcfdcddd33e858f8385f6b876af3c9f73d96665c Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Wed, 22 Dec 2021 16:36:30 +0000 Subject: [PATCH] Add 2017 Day 25 puzzles --- 2017/puzzle-25-01.cc | 110 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 2017/puzzle-25-01.cc diff --git a/2017/puzzle-25-01.cc b/2017/puzzle-25-01.cc new file mode 100644 index 0000000..da532d2 --- /dev/null +++ b/2017/puzzle-25-01.cc @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include + +using Int = long; +using StateName = char; + +struct SubInstruction +{ + bool write_; + Int move_delta_; + StateName next_state_; +}; + +struct Instruction +{ + [[nodiscard]] auto write(bool value) const noexcept -> bool + { + return subinstructions_[value ? 1 : 0].write_; + } + + [[nodiscard]] auto move_delta(bool value) const noexcept -> Int + { + return subinstructions_[value ? 1 : 0].move_delta_; + } + + [[nodiscard]] auto next_state(bool value) const noexcept -> StateName + { + return subinstructions_[value ? 1 : 0].next_state_; + } + + std::array subinstructions_; +}; + +auto main() -> int +{ + std::map state_machine; + std::regex begin_state_re{"Begin in state (.)."}; + std::regex step_count_re{"Perform a diagnostic checksum after (\\d+) steps."}; + std::regex in_state_re{"In state (.):"}; + std::regex if_current_value_re{" If the current value is (.):"}; + std::regex write_re{" - Write the value (.)."}; + std::regex move_re{" - Move one slot to the (left|right)."}; + std::regex next_state_re{" - Continue with state (.)."}; + + std::string line; + StateName current_state{'\0'}; + unsigned long step_count{0}; + unsigned current_value{2}; + + auto it{state_machine.end()}; + while (std::getline(std::cin, line) && line != "END") { + std::smatch m; + if (std::regex_search(line, m, begin_state_re)) { + assert(current_state == '\0'); + current_state = m.str(1)[0]; + } + else if (std::regex_search(line, m, step_count_re)) { + assert(step_count == 0); + step_count = std::stoul(m.str(1)); + } + else if (std::regex_search(line, m, in_state_re)) { + auto [it2, success] = state_machine.insert({m.str(1)[0], {}}); + assert(success); + it = it2; + current_value = 2; + } + else if (std::regex_search(line, m, if_current_value_re)) { + assert(it != state_machine.end()); + current_value = m.str(1)[0] - '0'; + assert(current_value == 0 || current_value == 1); + } + else if (std::regex_search(line, m, write_re)) { + assert(it != state_machine.end()); + assert(current_value != 2); + it->second.subinstructions_[current_value].write_ = m.str(1) == "1"; + } + else if (std::regex_search(line, m, move_re)) { + assert(it != state_machine.end()); + assert(current_value != 2); + it->second.subinstructions_[current_value].move_delta_ = m.str(1) == "left" ? -1 : 1; + } + else if (std::regex_search(line, m, next_state_re)) { + assert(it != state_machine.end()); + assert(current_value != 2); + it->second.subinstructions_[current_value].next_state_ = m.str(1)[0]; + } + } + + std::unordered_set marked; + Int pos{0}; + for (unsigned long i{0}; i < step_count; ++i) { + auto it{state_machine.find(current_state)}; + assert(it != state_machine.end()); + auto const& subinstruction = it->second.subinstructions_[marked.contains(pos) ? 1 : 0]; + if (subinstruction.write_) { + marked.insert(pos); + } + else { + marked.erase(pos); + } + pos += subinstruction.move_delta_; + current_state = subinstruction.next_state_; + } + + std::cout << "Number marked: " << marked.size() << '\n'; +}