AoC code coverage
Current view: top level - puzzles/2025 - Day05.cpp (source / functions) Coverage Total Hit
Test: master Lines: 90.5 % 42 38
Test Date: 2025-12-11 19:43:23 Functions: 66.7 % 6 4

            Line data    Source code
       1              : #include "PuzzleImpl.h"
       2              : 
       3              : #include "LinewiseInput.h"
       4              : #include "Parsing.h"
       5              : 
       6              : #include <algorithm>
       7              : #include <string_view>
       8              : #include <vector>
       9              : 
      10              : namespace {
      11              : 
      12              : struct Range {
      13              :   uint64_t begin;
      14              :   uint64_t end;
      15              : 
      16            0 :   [[nodiscard]] bool contains(uint64_t value) const { return value >= begin && value < end; }
      17            0 :   [[nodiscard]] bool intersects(Range const &other) const {
      18            0 :     return begin < other.end && end > other.begin;
      19            0 :   }
      20           78 :   [[nodiscard]] uint64_t size() const { return end - begin; }
      21              : };
      22              : 
      23              : auto parse(std::string_view const input) {
      24              :   LinewiseInput lines{input};
      25              :   auto blankLineIt = std::ranges::find(lines, "");
      26              :   std::vector<Range> ranges;
      27              :   ranges.reserve(std::distance(lines.begin(), blankLineIt));
      28              :   for (auto it = lines.begin(); it != blankLineIt; ++it) {
      29              :     auto dashIt = std::ranges::find(*it, '-');
      30              :     ranges.emplace_back(parseInt<uint64_t>({it->begin(), dashIt}),
      31              :                         parseInt<uint64_t>({std::next(dashIt), it->end()}) + 1u);
      32              :   }
      33              :   std::vector<uint64_t> ids;
      34              :   ids.reserve(std::distance(std::next(blankLineIt), lines.end()));
      35              :   for (auto it = std::next(blankLineIt); it != lines.end(); ++it) {
      36              :     ids.push_back(parseInt<uint64_t>(*it));
      37              :   }
      38              :   return std::make_tuple(std::move(ranges), std::move(ids));
      39              : }
      40              : 
      41            2 : void sortAndMergeRanges(std::vector<Range> &ranges) {
      42            2 :   std::ranges::sort(ranges, {}, &Range::begin);
      43              : 
      44            2 :   auto outIt = ranges.begin();
      45          158 :   for (auto it = ranges.begin(); it != ranges.end();) {
      46          156 :     *outIt = *it++;
      47          374 :     for (; it != ranges.end() && it->begin <= outIt->end; ++it) {
      48          218 :       outIt->end = std::max(outIt->end, it->end);
      49          218 :     }
      50          156 :     ++outIt;
      51          156 :   }
      52              : 
      53            2 :   ranges.erase(outIt, ranges.end());
      54            2 : }
      55              : 
      56              : } // namespace
      57              : 
      58            1 : template <> std::string solvePart1<2025, 5>(std::string_view const input) {
      59            1 :   auto [ranges, ids] = parse(input);
      60            1 :   sortAndMergeRanges(ranges);
      61            1 :   std::ranges::sort(ids);
      62            1 :   uint64_t cnt = 0;
      63            1 :   auto rangeIt = ranges.begin();
      64            1 :   auto idIt = ids.begin();
      65         1078 :   while (rangeIt != ranges.end() && idIt != ids.end()) {
      66         1077 :     if (*idIt < rangeIt->begin) {
      67          138 :       ++idIt;
      68          939 :     } else if (*idIt >= rangeIt->end) {
      69           77 :       ++rangeIt;
      70          862 :     } else {
      71          862 :       ++cnt;
      72          862 :       ++idIt;
      73          862 :     }
      74         1077 :   }
      75            1 :   return std::to_string(cnt);
      76            1 : }
      77              : 
      78            1 : template <> std::string solvePart2<2025, 5>(std::string_view const input) {
      79            1 :   auto [ranges, _] = parse(input);
      80            1 :   sortAndMergeRanges(ranges);
      81              : 
      82            1 :   return std::to_string(std::ranges::fold_left(ranges | std::views::transform(&Range::size),
      83            1 :                                                uint64_t{0}, std::plus{}));
      84            1 : }
        

Generated by: LCOV version 2.0-1