From 825f08d01e2691980ed4604992d4058dcc5dbbde Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 19 Dec 2019 20:57:28 +0100 Subject: [PATCH] Implement day 19 part 2. --- 2019/src/day19.cpp | 79 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/2019/src/day19.cpp b/2019/src/day19.cpp index e1ee29a..15eea3c 100644 --- a/2019/src/day19.cpp +++ b/2019/src/day19.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "days.hpp" #include "utils.hpp" @@ -17,42 +18,72 @@ namespace { return output_buffer.front(); } + + class Beam { + private: + aoc2019::IntCodeComputer computer; + std::int64_t last_width = 1; + std::int64_t last_start = 0; + std::int64_t y = 0; + + public: + Beam(std::istream &input) : computer(input) {}; + + std::pair next() { + auto x = last_start; + + while (!bounds_check(computer, x, y)) { + ++x; + } + + last_start = x; + x += last_width - 1; + + while (bounds_check(computer, x, y)) { + ++x; + } + + last_width = x - last_start; + ++y; + + return {last_start, last_width}; + } + }; } void aoc2019::day19_part1(std::istream &input, std::ostream &output) { - IntCodeComputer computer(input); + Beam beam(input); std::int64_t covered = 0; - int last_width = 1; - int last_start = 0; for (std::int64_t y = 0; y < 50; ++y) { - auto x = last_start; + const auto[start, width] = beam.next(); - while (!bounds_check(computer, x, y) && x < 50) { - ++x; - } + if (start >= 50) break; - if (x == 50) break; - - last_start = x; - x += last_width - 1; - - if (!bounds_check(computer, x, y)) { - std::cerr << x << "," << y << "," << covered << std::endl; - throw std::logic_error("Assumption false"); - } - - while (bounds_check(computer, x, y) && x < 50) { - ++x; - } - - last_width = x - last_start; - covered += last_width; + covered += std::min(50 - start, width); } output << covered << std::endl; } void aoc2019::day19_part2(std::istream &input, std::ostream &output) { - output << "Not implemented\n"; + Beam beam(input); + std::queue beam_ends; + + constexpr std::int64_t DIMENSION = 100; + + for (std::int64_t y = 0; true; ++y) { + const auto[start, width] = beam.next(); + + beam_ends.push(start + width); + if (beam_ends.size() == DIMENSION) { + auto end = beam_ends.front(); + if (end - start >= DIMENSION) { + auto result = start * 10000 + y - DIMENSION + 1; + output << result << std::endl; + return; + } + beam_ends.pop(); + } + } }