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

            Line data    Source code
       1              : #include "IntegerCast.h"
       2              : #include "LinewiseInput.h"
       3              : #include "Parsing.h"
       4              : #include "PuzzleImpl.h"
       5              : 
       6              : #include <libassert/assert.hpp>
       7              : 
       8              : #include <cstdint>
       9              : #include <numeric>
      10              : #include <string_view>
      11              : 
      12              : namespace {
      13              : 
      14          200 : int64_t extrapolateMeasurementBack(std::string_view const measurement) {
      15          200 :   std::vector<int64_t> derivativesBuffer = parseRange<int64_t>(measurement);
      16          200 :   std::span<int64_t> derivatives(derivativesBuffer);
      17              : 
      18          200 :   int64_t result = derivatives.back();
      19          200 :   bool allZero = false;
      20         2372 :   while (!allZero) {
      21         2172 :     DEBUG_ASSERT(derivatives.size() > 1U);
      22         2172 :     allZero = true;
      23        32356 :     for (size_t i = 1; i < derivatives.size(); ++i) {
      24        30184 :       derivatives[i - 1] = derivatives[i] - derivatives[i - 1];
      25        30184 :       allZero = allZero && derivatives[i - 1] == 0;
      26        30184 :     }
      27         2172 :     derivatives = std::span(derivatives.data(), derivatives.size() - 1u);
      28         2172 :     result += derivatives.back();
      29         2172 :   }
      30          200 :   return result;
      31          200 : }
      32              : 
      33          200 : int64_t extrapolateMeasurementFront(std::string_view const measurement) {
      34          200 :   std::vector<int64_t> derivativesBuffer = parseRange<int64_t>(measurement);
      35          200 :   std::span<int64_t> derivatives(derivativesBuffer);
      36              : 
      37          200 :   int64_t result = derivatives.front();
      38          200 :   bool allZero = false;
      39          200 :   int64_t sign = -1;
      40         2372 :   while (!allZero) {
      41         2172 :     DEBUG_ASSERT(derivatives.size() > 1U);
      42         2172 :     allZero = true;
      43        32356 :     for (size_t i = 1; i < derivatives.size(); ++i) {
      44        30184 :       derivatives[i - 1] = derivatives[i] - derivatives[i - 1];
      45        30184 :       allZero = allZero && derivatives[i - 1] == 0;
      46        30184 :     }
      47         2172 :     derivatives = std::span(derivatives.data(), derivatives.size() - 1u);
      48         2172 :     result += sign * derivatives.front();
      49         2172 :     sign *= -1;
      50         2172 :   }
      51          200 :   return result;
      52          200 : }
      53              : 
      54              : } // namespace
      55              : 
      56            1 : template <> size_t part1<2023, 9>(std::string_view const input) {
      57            1 :   LinewiseInput const lines(input);
      58              : 
      59            1 :   return integerCast<size_t>(std::transform_reduce(lines.begin(), lines.end(), int64_t(0),
      60            1 :                                                    std::plus<>(), extrapolateMeasurementBack));
      61            1 : }
      62              : 
      63            1 : template <> size_t part2<2023, 9>(std::string_view const input) {
      64            1 :   LinewiseInput const lines(input);
      65              : 
      66            1 :   return integerCast<size_t>(std::transform_reduce(lines.begin(), lines.end(), int64_t(0),
      67            1 :                                                    std::plus<>(), extrapolateMeasurementFront));
      68            1 : }
        

Generated by: LCOV version 2.0-1