AoC code coverage
Current view: top level - puzzles/2024 - Day22.cpp (source / functions) Coverage Total Hit
Test: master Lines: 100.0 % 44 44
Test Date: 2025-07-28 10:53:57 Functions: 100.0 % 3 3

            Line data    Source code
       1              : #include "PuzzleImpl.h"
       2              : 
       3              : #include "IntegerCast.h"
       4              : #include "Parsing.h"
       5              : #include "Views.h"
       6              : 
       7              : #include "experimental/mdspan"
       8              : #include "fmt/format.h"
       9              : #include "fmt/ranges.h"
      10              : 
      11              : #include <algorithm>
      12              : #include <cstddef>
      13              : #include <map>
      14              : #include <set>
      15              : #include <string_view>
      16              : #include <vector>
      17              : 
      18              : using namespace std::literals;
      19              : 
      20              : namespace {
      21              : 
      22      7148000 : uint64_t next(uint64_t n) {
      23      7148000 :   constexpr uint64_t modulo = 16777216u;
      24      7148000 :   n ^= n << 6u;
      25      7148000 :   n %= modulo;
      26      7148000 :   n ^= n >> 5u;
      27      7148000 :   n %= modulo;
      28      7148000 :   n ^= n << 11u;
      29      7148000 :   return n % modulo;
      30      7148000 : }
      31              : 
      32              : } // namespace
      33              : 
      34            1 : template <> size_t part1<2024, 22>(std::string_view const input) {
      35            1 :   std::vector<uint64_t> secretNumbers = parseIntegerRange<uint64_t>(input, '\n');
      36              : 
      37            1 :   for (auto &n : secretNumbers)
      38      3575787 :     for (unsigned i = 0; i < 2000; ++i) {
      39      3574000 :       n = next(n);
      40      3574000 :     }
      41              : 
      42            1 :   return std::ranges::fold_left(secretNumbers, uint64_t(0), std::plus{});
      43            1 : }
      44              : 
      45            1 : template <> size_t part2<2024, 22>(std::string_view const input) {
      46            1 :   std::vector<uint64_t> secretNumbers = parseIntegerRange<uint64_t>(input, '\n');
      47              : 
      48            1 :   using Extents = std::experimental::extents<int, 19u, 19u, 19u, 19u>;
      49            1 :   std::array<bool, integerCast<std::size_t>(19u * 19u * 19u * 19u)> priceChangesSeenData{};
      50            1 :   std::experimental::mdspan<bool, Extents> priceChangesSeen(priceChangesSeenData.data());
      51            1 :   priceChangesSeen = std::experimental::mdspan<bool, Extents>(&priceChangesSeen[9, 9, 9, 9]);
      52              : 
      53            1 :   std::array<int, integerCast<std::size_t>(19u * 19u * 19u * 19u)> seqPricesData{};
      54            1 :   std::experimental::mdspan<int, Extents> seqPrices(seqPricesData.data());
      55            1 :   seqPrices = std::experimental::mdspan<int, Extents>(&seqPrices[9, 9, 9, 9]);
      56              : 
      57         1787 :   for (auto &n : secretNumbers) {
      58         1787 :     std::ranges::fill(priceChangesSeenData, false);
      59         1787 :     int8_t lastPrice = 0;
      60         1787 :     std::array<int8_t, 4u> priceDelta{};
      61      3575787 :     for (unsigned i = 0; i < 2000; ++i) {
      62      3574000 :       n = next(n);
      63      3574000 :       auto const price = integerCast<int8_t>(n % 10);
      64      3574000 :       std::ranges::rotate(priceDelta, std::next(priceDelta.begin()));
      65      3574000 :       priceDelta.back() = integerCast<int8_t>(lastPrice - price);
      66      3574000 :       lastPrice = price;
      67              : 
      68      3574000 :       if (i > 3 && !priceChangesSeen[priceDelta]) {
      69      3448949 :         priceChangesSeen[priceDelta] = true;
      70      3448949 :         seqPrices[priceDelta] += price;
      71      3448949 :       }
      72      3574000 :     }
      73         1787 :   }
      74            1 :   return std::ranges::max(seqPricesData);
      75            1 : }
        

Generated by: LCOV version 2.0-1