From f540d823a3640636d94942faf444dbe5fc4fea47 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Mon, 6 Dec 2021 16:16:39 +0000 Subject: [PATCH] Add 2016 day 13 puzzles --- 2016/puzzle-13-01.cc | 115 +++++++++++++++++++++++++++++++++++++++++++ 2016/puzzle-13-02.cc | 115 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 2016/puzzle-13-01.cc create mode 100644 2016/puzzle-13-02.cc diff --git a/2016/puzzle-13-01.cc b/2016/puzzle-13-01.cc new file mode 100644 index 0000000..bd1443f --- /dev/null +++ b/2016/puzzle-13-01.cc @@ -0,0 +1,115 @@ +// +// Created by Matthew Gretton-Dann on 06/12/2021. +// + +#include +#include +#include + +using Num = unsigned long; + +struct Node +{ + Node(Num x, Num y, Num cost) : x_(x), y_(y), cost_(cost) {} + + auto operator==(Node const& rhs) const noexcept -> bool { return x_ == rhs.x_ && y_ == rhs.y_; } + + auto operator<(Node const& rhs) const noexcept -> bool + { + return x_ < rhs.x_ || (x_ == rhs.x_ && y_ < rhs.y_); + } + + Num x() const noexcept { return x_; } + Num y() const noexcept { return y_; } + Num cost() const noexcept { return cost_; } + + Node move_left() { return {x_ - 1, y_, cost_ + 1}; } + Node move_up() { return {x_, y_ + 1, cost_ + 1}; } + Node move_right() { return {x_ + 1, y_, cost_ + 1}; } + Node move_down() { return {x_, y_ - 1, cost_ + 1}; } + +private: + Num x_; + Num y_; + Num cost_; +}; + +auto is_wall(Num num, Node const& node) +{ + Num value{num + node.x() * node.x() + 3 * node.x() + 2 * node.x() * node.y() + node.y() + + node.y() * node.y()}; + Num bit_count{0}; + while (value != 0) { + bit_count += value & 1; + value >>= 1; + } + return ((bit_count & 1) == 1) ? true : false; +} + +struct CostCompare +{ + constexpr auto operator()(Node const& lhs, Node const& rhs) const noexcept -> bool + { + return lhs.cost() < rhs.cost(); + } +}; + +using ToVisitSet = std::multiset; +using VisitedSet = std::set; + +void update_to_visit(ToVisitSet& to_visit, VisitedSet const& visited, Num key, Node const& n) +{ + if (is_wall(key, n)) { + return; + } + + if (visited.contains(n)) { + return; + } + + auto it{std::find(to_visit.begin(), to_visit.end(), n)}; + if (it == to_visit.end()) { + to_visit.insert(n); + } + else if (n.cost() < it->cost()) { + to_visit.erase(it); + to_visit.insert(n); + } +} + +auto main() -> int +{ + VisitedSet visited; + ToVisitSet to_visit; + + std::string line; + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read line.\n"; + return 1; + } + Num key{std::stoul(line)}; + + to_visit.insert(Node{1, 1, 0}); + while (!to_visit.empty()) { + auto it{to_visit.begin()}; + Node n(*it); + if (n.x() == 31 && n.y() == 39) { + std::cout << "Cost = " << n.cost(); + return 0; + } + + to_visit.erase(it); + visited.insert(n); + if (n.x() > 0) { + update_to_visit(to_visit, visited, key, n.move_left()); + } + if (n.y() > 0) { + update_to_visit(to_visit, visited, key, n.move_down()); + } + update_to_visit(to_visit, visited, key, n.move_right()); + update_to_visit(to_visit, visited, key, n.move_up()); + } + + std::cout << "No solution.\n"; + return 1; +} \ No newline at end of file diff --git a/2016/puzzle-13-02.cc b/2016/puzzle-13-02.cc new file mode 100644 index 0000000..60a4ca8 --- /dev/null +++ b/2016/puzzle-13-02.cc @@ -0,0 +1,115 @@ +// +// Created by Matthew Gretton-Dann on 06/12/2021. +// + +#include +#include +#include + +using Num = unsigned long; + +struct Node +{ + Node(Num x, Num y, Num cost) : x_(x), y_(y), cost_(cost) {} + + auto operator==(Node const& rhs) const noexcept -> bool { return x_ == rhs.x_ && y_ == rhs.y_; } + + auto operator<(Node const& rhs) const noexcept -> bool + { + return x_ < rhs.x_ || (x_ == rhs.x_ && y_ < rhs.y_); + } + + Num x() const noexcept { return x_; } + Num y() const noexcept { return y_; } + Num cost() const noexcept { return cost_; } + + Node move_left() { return {x_ - 1, y_, cost_ + 1}; } + Node move_up() { return {x_, y_ + 1, cost_ + 1}; } + Node move_right() { return {x_ + 1, y_, cost_ + 1}; } + Node move_down() { return {x_, y_ - 1, cost_ + 1}; } + +private: + Num x_; + Num y_; + Num cost_; +}; + +auto is_wall(Num num, Node const& node) +{ + Num value{num + node.x() * node.x() + 3 * node.x() + 2 * node.x() * node.y() + node.y() + + node.y() * node.y()}; + Num bit_count{0}; + while (value != 0) { + bit_count += value & 1; + value >>= 1; + } + return ((bit_count & 1) == 1) ? true : false; +} + +struct CostCompare +{ + constexpr auto operator()(Node const& lhs, Node const& rhs) const noexcept -> bool + { + return lhs.cost() < rhs.cost(); + } +}; + +using ToVisitSet = std::multiset; +using VisitedSet = std::set; + +void update_to_visit(ToVisitSet& to_visit, VisitedSet const& visited, Num key, Node const& n) +{ + if (is_wall(key, n)) { + return; + } + + if (visited.contains(n)) { + return; + } + + if (n.cost() > 50) { + return; + } + + auto it{std::find(to_visit.begin(), to_visit.end(), n)}; + if (it == to_visit.end()) { + to_visit.insert(n); + } + else if (n.cost() < it->cost()) { + to_visit.erase(it); + to_visit.insert(n); + } +} + +auto main() -> int +{ + VisitedSet visited; + ToVisitSet to_visit; + + std::string line; + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read line.\n"; + return 1; + } + Num key{std::stoul(line)}; + + to_visit.insert(Node{1, 1, 0}); + while (!to_visit.empty()) { + auto it{to_visit.begin()}; + Node n(*it); + + to_visit.erase(it); + visited.insert(n); + if (n.x() > 0) { + update_to_visit(to_visit, visited, key, n.move_left()); + } + if (n.y() > 0) { + update_to_visit(to_visit, visited, key, n.move_down()); + } + update_to_visit(to_visit, visited, key, n.move_right()); + update_to_visit(to_visit, visited, key, n.move_up()); + } + + std::cout << "Number of visited locations: " << visited.size() << '\n'; + return 0; +} \ No newline at end of file