From 5111d633b76d1e81769b2c47bc4311e8103c69a6 Mon Sep 17 00:00:00 2001 From: Thraix Date: Wed, 26 Aug 2026 23:13:22 +0200 Subject: [PATCH] Add solution for 2016 Day 15 --- res/2016/day15/test_input.txt | 3 +++ src/2016/Day15.cpp | 43 ++++++++++++++++++++++++++++------- src/common/lib/Helper.h | 34 ++++++++++++++++++++------- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/res/2016/day15/test_input.txt b/res/2016/day15/test_input.txt index e69de29..e52aa7a 100644 --- a/res/2016/day15/test_input.txt +++ b/res/2016/day15/test_input.txt @@ -0,0 +1,3 @@ +Disc #1 has 5 positions; at time=0, it is at position 4. +Disc #2 has 2 positions; at time=0, it is at position 1. +Disc #2 has 3 positions; at time=0, it is at position 2. diff --git a/src/2016/Day15.cpp b/src/2016/Day15.cpp index f9c2032..8a1443b 100644 --- a/src/2016/Day15.cpp +++ b/src/2016/Day15.cpp @@ -2,30 +2,57 @@ namespace y2016::day15 { - REGISTER_DAY(2016, Day15, std::vector, int); + struct Disc + { + int positions; + int position; + }; - REGISTER_TEST_EXAMPLE(2016, Day15, ExampleInput, 1, 0); - REGISTER_TEST(2016, Day15, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2016, Day15, ExampleInput, 2, 0); - REGISTER_TEST(2016, Day15, Input, 2, 0); + REGISTER_DAY(2016, Day15, std::vector, int64_t); + + REGISTER_TEST_EXAMPLE(2016, Day15, ExampleInput, 1, 25); + REGISTER_TEST(2016, Day15, Input, 1, 400589); + REGISTER_TEST_EXAMPLE(2016, Day15, ExampleInput, 2, 205); + REGISTER_TEST(2016, Day15, Input, 2, 3045959); READ_INPUT(input) { - std::vector vec; + std::vector vec; std::string str; while (getline(input, str)) { + std::stringstream ss{str}; + int i; + Disc disc; + ss >> "Disc #" >> i >> "has " >> disc.positions >> "positions; at time=" >> i >> ", it is at position " >> + disc.position; + vec.emplace_back(disc); } return vec; } + int64_t Solve(const std::vector& discs) + { + std::vector starts; + std::vector mods; + std::vector remainders(discs.size(), 0); + for (int j = 0; j < discs.size(); j++) + { + starts.emplace_back(discs[j].position + j + 1); + mods.emplace_back(discs[j].positions); + } + return Helper::ChineseRemainderTheorem(mods, remainders, starts); + } + OUTPUT1(input) { - return 0; + return Solve(input); } OUTPUT2(input) { - return 0; + auto discs = input; + discs.emplace_back(Disc{11, 0}); + return Solve(discs); } } diff --git a/src/common/lib/Helper.h b/src/common/lib/Helper.h index 76af015..fba0459 100644 --- a/src/common/lib/Helper.h +++ b/src/common/lib/Helper.h @@ -600,12 +600,15 @@ struct Helper return Index2D{-1, -1}; } - static int64_t ChineseRemainderTheoremTwo(int64_t mod1, int64_t mod2, int64_t res1, int64_t res2) + // Solve for N: + // remainder1 = N % mod1 + // remainder2 = N % mod2 + static int64_t ChineseRemainderTheoremTwo(int64_t mod1, int64_t mod2, int64_t remainder1, int64_t remainder2) { - int64_t i = res1; + int64_t i = remainder1; while (true) { - if (i % mod2 == res2) + if (i % mod2 == remainder2) return i; i += mod1; @@ -613,17 +616,32 @@ struct Helper return 0; } - static int64_t ChineseRemainderTheorem(const std::vector& mods, const std::vector& results) + // Solve for N: + // remainders = N % mods + static int64_t ChineseRemainderTheorem(const std::vector& mods, const std::vector& remainders) { int64_t currentMod = mods.front(); - int64_t currentRes = results.front(); + int64_t currentRem = remainders.front(); for (int i = 1; i < mods.size(); i++) { - int64_t result = ChineseRemainderTheoremTwo(currentMod, mods[i], currentRes, results[i]); - currentRes = result; + int64_t result = ChineseRemainderTheoremTwo(currentMod, mods[i], currentRem, remainders[i]); + currentRem = result; currentMod = currentMod * mods[i]; } - return currentRes; + return currentRem; + } + + // Solve for N: + // remainders = (start + N) % mods + static int64_t ChineseRemainderTheorem(const std::vector& mods, + std::vector remainders, + const std::vector& starts) + { + for (int i = 0; i < mods.size(); i++) + { + remainders[i] = ((remainders[i] - starts[i]) % mods[i] + mods[i]) % mods[i]; + } + return ChineseRemainderTheorem(mods, remainders); } static uint64_t FastExponentiation(uint64_t start, uint64_t multiplication, uint64_t power, uint64_t mod)