From 602b46eac77742b602231f89d88cfa986968c39f Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Mon, 6 Dec 2021 20:17:55 +0000 Subject: [PATCH] Add 2016 day 15 puzzles --- 2016/puzzle-15-01.cc | 64 ++++++++++++++++++++++++++++++++++++++++++ 2016/puzzle-15-02.cc | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 2016/puzzle-15-01.cc create mode 100644 2016/puzzle-15-02.cc diff --git a/2016/puzzle-15-01.cc b/2016/puzzle-15-01.cc new file mode 100644 index 0000000..de2861c --- /dev/null +++ b/2016/puzzle-15-01.cc @@ -0,0 +1,64 @@ +// +// Created by Matthew Gretton-Dann on 06/12/2021. +// + +#include +#include +#include +#include + +struct Circle +{ + explicit Circle(std::string const& s) + { + std::regex re{"Disc #\\d has (\\d+) positions; at time=0, it is at position (\\d+)."}; + std::smatch m; + if (!std::regex_search(s, m, re)) { + abort(); + } + circumference_ = std::stoul(m.str(1)); + start_ = std::stoul(m.str(2)); + } + + auto circumference() const noexcept -> unsigned { return circumference_; } + auto start() const noexcept -> unsigned { return start_; } + +private: + unsigned circumference_; + unsigned start_; +}; + +auto main() -> int +{ + std::string line; + std::vector circles; + while (std::getline(std::cin, line)) { + circles.emplace_back(line); + } + + unsigned time{0}; + unsigned adder{1}; + unsigned offset{0}; + /* For each circle we want the value of cirle.start() + offset + time to be 0 (mod number of + * positions). Where the offset is how many circles we've dropped through (starting at 1), and + * time is the time released. + * + * Once we've worked out the time for the first circle, all future + * potential releases will be (t1 + N * pos1), for circle 2 it will be (t2 + N * pos1 * pos2). + * We use adder to keep track of this. + * + * We assume all circumferences are co-prime. + */ + for (auto const& circle : circles) { + ++offset; + while ((circle.start() + offset + time) % circle.circumference() != 0) { + time += adder; + } + std::cout << "Circle start " << circle.start() << " Position " << circle.circumference() + << " release time " << time << '\n'; + adder *= circle.circumference(); + } + + std::cout << "Release time: " << time << '\n'; + return 0; +} \ No newline at end of file diff --git a/2016/puzzle-15-02.cc b/2016/puzzle-15-02.cc new file mode 100644 index 0000000..5b9a423 --- /dev/null +++ b/2016/puzzle-15-02.cc @@ -0,0 +1,67 @@ +// +// Created by Matthew Gretton-Dann on 06/12/2021. +// + +#include +#include +#include +#include + +struct Circle +{ + explicit Circle(std::string const& s) + { + std::regex re{"Disc #\\d has (\\d+) positions; at time=0, it is at position (\\d+)."}; + std::smatch m; + if (!std::regex_search(s, m, re)) { + abort(); + } + circumference_ = std::stoul(m.str(1)); + start_ = std::stoul(m.str(2)); + } + + Circle(unsigned circumference, unsigned start) : circumference_(circumference), start_(start) {} + + auto circumference() const noexcept -> unsigned { return circumference_; } + auto start() const noexcept -> unsigned { return start_; } + +private: + unsigned circumference_; + unsigned start_; +}; + +auto main() -> int +{ + std::string line; + std::vector circles; + while (std::getline(std::cin, line)) { + circles.emplace_back(line); + } + circles.emplace_back(11, 0); + + unsigned time{0}; + unsigned adder{1}; + unsigned offset{0}; + /* For each circle we want the value of cirle.start() + offset + time to be 0 (mod number of + * positions). Where the offset is how many circles we've dropped through (starting at 1), and + * time is the time released. + * + * Once we've worked out the time for the first circle, all future + * potential releases will be (t1 + N * pos1), for circle 2 it will be (t2 + N * pos1 * pos2). + * We use adder to keep track of this. + * + * We assume all circumferences are co-prime. + */ + for (auto const& circle : circles) { + ++offset; + while ((circle.start() + offset + time) % circle.circumference() != 0) { + time += adder; + } + std::cout << "Circle start " << circle.start() << " Position " << circle.circumference() + << " release time " << time << '\n'; + adder *= circle.circumference(); + } + + std::cout << "Release time: " << time << '\n'; + return 0; +} \ No newline at end of file