From 026f2eba2c2aecc0bd33ac658d4ac695c17bead0 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Thu, 15 Dec 2022 08:10:29 +0000 Subject: [PATCH] Add solutions for 2022 day 15. --- 2022/puzzle-15-01.cc | 96 +++++++++++++++++++++++++++++++++++++ 2022/puzzle-15-02.cc | 109 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 2022/puzzle-15-01.cc create mode 100644 2022/puzzle-15-02.cc diff --git a/2022/puzzle-15-01.cc b/2022/puzzle-15-01.cc new file mode 100644 index 0000000..64248eb --- /dev/null +++ b/2022/puzzle-15-01.cc @@ -0,0 +1,96 @@ +// +// Created by Matthew Gretton-Dann on 09/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; +using Range = std::pair; + +struct RangeCompare +{ + auto operator()(Range const& l, Range const& r) const noexcept -> bool + { + if (l.first < r.first) { + return true; + } + if (l.first == r.first && l.second < r.second) { + return true; + } + return false; + } +}; + +auto main() -> int +{ + Int const row{2000000}; + std::regex const re{ + R"(Sensor at x=(-?\d+), y=(-?\d+): closest beacon is at x=(-?\d+), y=(-?\d+))"}; + std::string line; + std::set ranges; + std::set beacons_on_row; + + while (std::getline(std::cin, line)) { + std::smatch m; + if (!std::regex_search(line, m, re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + + Int const sx{std::stoll(m.str(1))}; + Int const sy{std::stoll(m.str(2))}; + Int const bx{std::stoll(m.str(3))}; + Int const by{std::stoll(m.str(4))}; + + // Distance between sensor and beacon: + Int const dist{std::abs(sx - bx) + std::abs(sy - by)}; + // Distance(ish) to row we're interested in: + Int const row_dist{std::abs(sy - row)}; + std::cout << "Sensor (" << sx << ", " << sy << "):\n" + << " Nearest beacon is: " << bx << ", " << by << "\n" + << " Distance: " << dist << "\n" + << " y-Distance to row " << row << ": " << row_dist << "\n"; + // If that distance is non-negative then we have places the beacon can't be + if (row_dist <= dist) { + Int const x_dist{dist - row_dist}; + std::cout << " x distance left: " << x_dist << "\n" + << " Range: " << sx - x_dist << " - " << sx + x_dist + 1 << "\n"; + Range const missing{sx - x_dist, sx + x_dist + 1}; + ranges.insert(missing); + } + if (by == row) { + std::cout << " Beacon on row.\n"; + beacons_on_row.insert(bx); + } + } + + Int last_pos{std::numeric_limits::min()}; + UInt count{0}; + std::cout << "\n\n\n"; + for (auto const& r : ranges) { + assert(r.first < r.second); + std::cout << "Range: " << r.first << " - " << r.second << "\n"; + if (r.second < last_pos) { + std::cout << " Skipping\n"; + continue; + } + auto b{std::max(r.first, last_pos)}; + std::cout << " Taking range start as: " << b << '\n' + << " Adding to count: " << r.second - b << "\n"; + count += (r.second - b); + last_pos = r.second; + } + + std::cout << "Removing beacons we know are on the row: " << beacons_on_row.size() << "\n"; + count -= beacons_on_row.size(); + + std::cout << "No beacons in: " << count << " places.\n"; + return EXIT_SUCCESS; +} diff --git a/2022/puzzle-15-02.cc b/2022/puzzle-15-02.cc new file mode 100644 index 0000000..e1553b5 --- /dev/null +++ b/2022/puzzle-15-02.cc @@ -0,0 +1,109 @@ +// +// Created by Matthew Gretton-Dann on 09/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; +using Range = std::pair; + +struct RangeCompare +{ + auto operator()(Range const& l, Range const& r) const noexcept -> bool + { + if (l.first < r.first) { + return true; + } + if (l.first == r.first && l.second < r.second) { + return true; + } + return false; + } +}; + +auto main() -> int +{ + Int const max_row{4000000 + 1}; + std::regex const re{ + R"(Sensor at x=(-?\d+), y=(-?\d+): closest beacon is at x=(-?\d+), y=(-?\d+))"}; + std::string line; + std::vector> sensors; + while (std::getline(std::cin, line)) { + std::smatch m; + if (!std::regex_search(line, m, re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + Int const sx{std::stoll(m.str(1))}; + Int const sy{std::stoll(m.str(2))}; + Int const bx{std::stoll(m.str(3))}; + Int const by{std::stoll(m.str(4))}; + sensors.push_back({{sx, sy}, {bx, by}}); + } + + for (Int row{0}; row < max_row; ++row) { + if (row % 100'000 == 0) { + std::cout << " Row: " << row << "\n"; + std::flush(std::cout); + } + std::set ranges; + + for (auto const& sensor : sensors) { + Int const sx{sensor.first.first}; + Int const sy{sensor.first.second}; + Int const bx{sensor.second.first}; + Int const by{sensor.second.second}; + + // Distance between sensor and beacon: + Int const dist{std::abs(sx - bx) + std::abs(sy - by)}; + // Distance(ish) to row we're interested in: + Int const row_dist{std::abs(sy - row)}; + // If that distance is non-negative then we have places the beacon can't be + if (row_dist <= dist) { + Int const x_dist{dist - row_dist}; + Range const missing{sx - x_dist, sx + x_dist + 1}; + ranges.insert(missing); + } + } + + Int last_pos{0}; + UInt count{0}; + for (auto const& r : ranges) { + assert(r.first < r.second); + if (r.second < last_pos) { + continue; + } + auto b{std::max(r.first, last_pos)}; + auto e{std::min(r.second, max_row)}; + count += (e - b); + last_pos = e; + } + + if (count != max_row) { + std::cout << "Row interested in: " << row << "\n"; + std::cout << "Count = " << count << "\n"; + Int gap{0}; + for (auto const& r : ranges) { + assert(r.first < r.second); + if (r.second < gap) { + continue; + } + if (r.first > gap) { + std::cout << " Gap in " << gap << " - " << r.first << "\n"; + std::cout << "Score = " << gap * 4000000 + row << "\n"; + } + gap = std::min(r.second, max_row); + } + return EXIT_SUCCESS; + } + } + + return EXIT_FAILURE; +}