AoC code coverage
Current view: top level - puzzles/2022 - Day03.cpp (source / functions) Coverage Total Hit
Test: master Lines: 97.9 % 48 47
Test Date: 2025-07-28 10:53:57 Functions: 100.0 % 7 7

            Line data    Source code
       1              : #include "IntegerCast.h"
       2              : #include "LinewiseInput.h"
       3              : #include "PuzzleImpl.h"
       4              : 
       5              : #include <libassert/assert.hpp>
       6              : 
       7              : #include <algorithm>
       8              : #include <cctype>
       9              : #include <cstdint>
      10              : #include <iostream>
      11              : #include <numeric>
      12              : #include <string_view>
      13              : 
      14              : namespace {
      15              : 
      16          300 : char commonElement(std::string_view const contents) {
      17          300 :   auto middle = std::next(contents.begin(), integerCast<int64_t>(contents.size() / 2u));
      18          300 :   std::string a{contents.begin(), middle};
      19          300 :   std::string b{middle, contents.end()};
      20          300 :   std::ranges::sort(a);
      21          300 :   std::ranges::sort(b);
      22          300 :   auto aIt = a.begin();
      23          300 :   auto bIt = b.begin();
      24         4686 :   while (aIt != a.end() && bIt != b.end()) {
      25         4686 :     if (*aIt < *bIt)
      26         2210 :       ++aIt;
      27         2476 :     else if (*bIt < *aIt)
      28         2176 :       ++bIt;
      29          300 :     else
      30          300 :       return *aIt;
      31         4686 :   }
      32          300 :   PANIC("No common element!");
      33            0 : }
      34              : 
      35          100 : char findBadge(std::span<std::string_view const, 3u> const contents) {
      36          100 :   std::string result{contents.front()};
      37          100 :   std::ranges::sort(result);
      38              : 
      39          300 :   for (size_t i = 1; i < contents.size(); ++i) {
      40          200 :     std::string tmp{contents[i]};
      41          200 :     std::ranges::sort(tmp);
      42          200 :     result.erase(std::ranges::set_intersection(result, tmp, result.begin()).out, result.end());
      43          200 :   }
      44          100 :   ASSUME(!result.empty(), contents, result);
      45          100 :   ASSUME(result.front() == result.back(), contents, result);
      46          100 :   return result.front();
      47          100 : }
      48              : 
      49          400 : size_t priority(char const c) { return (std::islower(c)) ? 1u + c - 'a' : 27u + c - 'A'; }
      50              : 
      51              : } // namespace
      52              : 
      53            1 : template <> size_t part1<2022, 3>(std::string_view const input) {
      54            1 :   LinewiseInput const lines(input);
      55            1 :   return std::transform_reduce(
      56            1 :       lines.begin(), lines.end(), size_t(0), std::plus{},
      57          300 :       [](std::string_view const line) { return priority(commonElement(line)); });
      58            1 : }
      59              : 
      60            1 : template <> size_t part2<2022, 3>(std::string_view const input) {
      61            1 :   LinewiseInput const lines(input);
      62              : 
      63            1 :   std::vector<std::span<std::string_view const, 3u>> groups;
      64            1 :   groups.reserve(lines.size() / 3u);
      65          101 :   for (auto it = lines.begin(); it < lines.end(); it += 3) {
      66          100 :     groups.emplace_back(it, std::next(it, 3));
      67          100 :   }
      68              : 
      69            1 :   return std::transform_reduce(
      70            1 :       groups.begin(), groups.end(), size_t(0), std::plus{},
      71          100 :       [](std::span<std::string_view const, 3u> const group) { return priority(findBadge(group)); });
      72            1 : }
        

Generated by: LCOV version 2.0-1