AoC code coverage
Current view: top level - puzzles/2025 - Day02.cpp (source / functions) Coverage Total Hit
Test: master Lines: 98.6 % 74 73
Test Date: 2025-12-11 19:43:23 Functions: 83.3 % 6 5

            Line data    Source code
       1              : #include "PuzzleImpl.h"
       2              : 
       3              : #include "IntegerCast.h"
       4              : #include "Parsing.h"
       5              : 
       6              : #include <charconv>
       7              : #include <re2/re2.h>
       8              : 
       9              : #include <string_view>
      10              : 
      11              : #include <vector>
      12              : 
      13              : namespace {
      14              : 
      15              : struct Range {
      16            0 :   [[nodiscard]] bool contains(uint64_t x) const { return x >= from && x <= to; }
      17              : 
      18              :   uint64_t from;
      19              :   uint64_t to;
      20              : };
      21              : 
      22            2 : std::vector<Range> parseRanges(std::string_view const input) {
      23            2 :   std::vector<std::string_view> rangeStrings = split(input);
      24            2 :   std::vector<Range> result;
      25            2 :   result.reserve(rangeStrings.size());
      26            2 :   RE2 re(R"((\d+)-(\d+))");
      27            2 :   uint64_t from = 0;
      28            2 :   uint64_t to = 0;
      29           60 :   for (std::string_view const line : rangeStrings) {
      30           60 :     ASSERT(RE2::FullMatch(line, re, &from, &to));
      31           60 :     result.emplace_back(from, to);
      32           60 :   }
      33            2 :   return result;
      34            2 : }
      35              : 
      36      2070328 : bool isInvalidPart1(uint64_t const x) {
      37      2070328 :   std::array<char, std::numeric_limits<uint64_t>::digits10> buf{};
      38      2070328 :   std::to_chars_result res = std::to_chars(buf.begin(), buf.end(), x);
      39      2070328 :   ASSERT(res.ec == std::errc());
      40      2070328 :   std::string_view const sv{buf.data(), integerCast<size_t>(res.ptr - buf.data())};
      41      2070328 :   std::string_view const firstPart(sv.substr(0, sv.size() / 2));
      42      2070328 :   std::string_view const secondPart(sv.substr(sv.size() / 2));
      43      2070328 :   return firstPart == secondPart;
      44      2070328 : }
      45              : 
      46      2070328 : bool isInvalidPart2(uint64_t const x) {
      47      2070328 :   std::array<char, std::numeric_limits<uint64_t>::digits10> buf{};
      48      2070328 :   std::to_chars_result res = std::to_chars(buf.begin(), buf.end(), x);
      49      2070328 :   ASSERT(res.ec == std::errc());
      50      2070328 :   std::string_view const sv{buf.data(), integerCast<size_t>(res.ptr - buf.data())};
      51      9586586 :   for(size_t subLen = 1; subLen <= sv.size() / 2; ++subLen)
      52      7516881 :   {
      53      7516881 :     if(sv.size() % subLen != 0)
      54      2651858 :       continue;
      55      4865023 :     std::string_view const firstSubStr(sv.substr(0, subLen));
      56      5503026 :     for(size_t pos = subLen; pos < sv.size(); pos += subLen)
      57      5503026 :     {
      58      5503026 :       std::string_view const nextSubStr(sv.substr(pos, subLen));
      59      5503026 :       if(firstSubStr != nextSubStr)
      60      4864400 :         break;
      61       638626 :       if(pos + subLen == sv.size())
      62          623 :         return true;
      63       638626 :     }
      64      4865023 :   }
      65      2069705 :   return false;
      66      2070328 : }
      67              : 
      68              : } // namespace
      69              : 
      70            1 : template <> std::string solvePart1<2025, 2>(std::string_view const input) {
      71            1 :   std::vector<Range> ranges = parseRanges(input);
      72            1 :   uint64_t sum = 0;
      73            1 :   for(auto const & r : ranges)
      74           30 :   {
      75      2070358 :     for(uint64_t i = r.from; i <= r.to; ++i)
      76      2070328 :     {
      77      2070328 :       if(isInvalidPart1(i))
      78          565 :       {
      79          565 :         sum += i;
      80          565 :       }
      81      2070328 :     }
      82           30 :   }
      83            1 :   return std::to_string(sum);
      84            1 : }
      85              : 
      86            1 : template <> std::string solvePart2<2025, 2>(std::string_view const input) {
      87            1 :   std::vector<Range> ranges = parseRanges(input);
      88            1 :   uint64_t sum = 0;
      89            1 :   for(auto const & r : ranges)
      90           30 :   {
      91      2070358 :     for(uint64_t i = r.from; i <= r.to; ++i)
      92      2070328 :     {
      93      2070328 :       if(isInvalidPart2(i))
      94          623 :       {
      95          623 :         sum += i;
      96          623 :       }
      97      2070328 :     }
      98           30 :   }
      99            1 :   return std::to_string(sum);
     100            1 : }
        

Generated by: LCOV version 2.0-1