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

            Line data    Source code
       1              : #include "LinewiseInput.h"
       2              : #include "PuzzleImpl.h"
       3              : 
       4              : #include <libassert/assert.hpp>
       5              : 
       6              : #include <algorithm>
       7              : #include <array>
       8              : #include <iterator>
       9              : #include <string_view>
      10              : #include <unordered_set>
      11              : 
      12              : namespace {
      13              : 
      14              : using namespace std::string_view_literals;
      15              : 
      16         1000 : bool hasThreeVowels(std::string_view const word) {
      17         1000 :   static std::string_view constexpr vowels{"aeiou"};
      18        16000 :   return std::ranges::count_if(word, [&](char const c) { return vowels.contains(c); }) >= 3u;
      19         1000 : }
      20              : 
      21          631 : bool containsDoubleLetter(std::string_view const word) {
      22          631 :   return std::ranges::adjacent_find(word) != word.end();
      23          631 : }
      24              : 
      25          260 : bool noBadSubstrings(std::string_view const word) {
      26          260 :   static std::array constexpr badSubstrings = {"ab"sv, "cd"sv, "pq"sv, "xy"sv};
      27          999 :   return std::ranges::none_of(badSubstrings, [&](std::string_view const badSubstring) {
      28          999 :     return word.contains(badSubstring);
      29          999 :   });
      30          260 : }
      31              : 
      32         1000 : bool hasDoubleLetterPair(std::string_view const word) {
      33        14586 :   for (auto it = word.begin(); it != std::prev(word.end(), 1); ++it) {
      34        13715 :     std::string_view const pair(it, 2u);
      35        13715 :     std::string_view const remainder(std::next(it, 2), word.end());
      36        13715 :     if (remainder.contains(pair))
      37          129 :       return true;
      38        13715 :   }
      39          871 :   return false;
      40         1000 : }
      41              : 
      42          129 : bool hasMirrorRepeat(std::string_view const word) {
      43         1431 :   for (auto it = word.begin(); it != std::prev(word.end(), 2); ++it) {
      44         1371 :     std::string_view const letters(it, 3u);
      45         1371 :     if (letters.front() == letters.back())
      46           69 :       return true;
      47         1371 :   }
      48           60 :   return false;
      49          129 : }
      50              : 
      51              : } // namespace
      52              : 
      53            1 : template <> size_t part1<2015, 5>(std::string_view const input) {
      54            1 :   LinewiseInput lines(input);
      55         1000 :   return std::ranges::count_if(lines, [](std::string_view const line) {
      56         1000 :     return hasThreeVowels(line) && containsDoubleLetter(line) && noBadSubstrings(line);
      57         1000 :   });
      58            1 : }
      59              : 
      60            1 : template <> size_t part2<2015, 5>(std::string_view const input) {
      61            1 :   LinewiseInput lines(input);
      62         1000 :   return std::ranges::count_if(lines, [](std::string_view const line) {
      63         1000 :     return hasDoubleLetterPair(line) && hasMirrorRepeat(line);
      64         1000 :   });
      65            1 : }
        

Generated by: LCOV version 2.0-1