AoC code coverage
Current view: top level - puzzles/2024 - Day06.cpp (source / functions) Coverage Total Hit
Test: master Lines: 100.0 % 51 51
Test Date: 2025-12-11 19:43:23 Functions: 100.0 % 8 8

            Line data    Source code
       1              : #include "Grid2d.h"
       2              : #include "LinewiseInput.h"
       3              : #include "PuzzleImpl.h"
       4              : 
       5              : #include <algorithm>
       6              : #include <string>
       7              : 
       8              : namespace {
       9              : 
      10              : std::array<Vec2<int>, 4u> constexpr dirs{{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}};
      11              : 
      12              : struct Guard {
      13              : 
      14      3091284 :   [[nodiscard]] Grid2d<char>::Coord next() const { return pos + dirs[dirIdx]; }
      15       102768 :   void turn() { dirIdx = (dirIdx + 1) % 4; }
      16      2973720 :   void move() { pos = pos + dirs[dirIdx]; }
      17              : 
      18              :   Grid2d<char>::Coord pos;
      19              :   int dirIdx;
      20              : };
      21              : 
      22      3076488 : void moveGuard(Guard &guard, Grid2d<char> const &grid) {
      23      3076488 :   if (grid[guard.next()] == '#')
      24       102768 :     guard.turn();
      25      2973720 :   else
      26      2973720 :     guard.move();
      27      3076488 : }
      28              : 
      29      3072736 : bool guardToPath(Grid2d<unsigned char> &path, Guard const &guard) {
      30      3072736 :   unsigned int const mask = 1 << guard.dirIdx;
      31      3072736 :   unsigned char &v = path[guard.pos];
      32      3072736 :   if ((v & mask) != 0u)
      33         1602 :     return false;
      34              : 
      35      3071134 :   v = v | mask;
      36      3071134 :   return true;
      37      3072736 : }
      38              : 
      39         4721 : bool pathHasCycle(Guard guard, Grid2d<char> const &grid, Grid2d<unsigned char> path) {
      40      3070501 :   for (; grid[guard.pos] != '*'; moveGuard(guard, grid)) {
      41      3067382 :     if (!guardToPath(path, guard))
      42         1602 :       return true;
      43      3067382 :   }
      44         3119 :   return false;
      45         4721 : }
      46              : 
      47              : } // namespace
      48              : 
      49            1 : template <> std::string solvePart1<2024, 6>(std::string_view const input) {
      50            1 :   LinewiseInput linewise(input);
      51            1 :   Grid2d<char> grid = linewise.makeCharGrid2dWithGhostLayers(1, '*');
      52              : 
      53         5355 :   for (Guard guard{.pos = grid.find('^'), .dirIdx = 0}; grid[guard.pos] != '*';
      54         5354 :        moveGuard(guard, grid)) {
      55         5354 :     grid[guard.pos] = 'X';
      56         5354 :   }
      57              : 
      58            1 :   return std::to_string(grid.count('X'));
      59            1 : }
      60              : 
      61            1 : template <> std::string solvePart2<2024, 6>(std::string_view const input) {
      62            1 :   LinewiseInput linewise(input);
      63            1 :   Grid2d<char> grid = linewise.makeCharGrid2dWithGhostLayers(1, '*');
      64            1 :   Grid2d<unsigned char> path(grid.xSize(), grid.ySize());
      65              : 
      66            1 :   int cnt = 0;
      67         5355 :   for (Guard guard{.pos = grid.find('^'), .dirIdx = 0}; grid[guard.pos] != '*';
      68         5354 :        moveGuard(guard, grid)) {
      69         5354 :     if (grid[guard.next()] == '.') {
      70         4721 :       grid[guard.next()] = '#';
      71         4721 :       if (pathHasCycle(guard, grid, path))
      72         1602 :         ++cnt;
      73         4721 :       grid[guard.next()] = '.';
      74         4721 :     }
      75         5354 :     guardToPath(path, guard);
      76         5354 :     grid[guard.pos] = 'X';
      77         5354 :   }
      78              : 
      79            1 :   return std::to_string(cnt);
      80            1 : }
        

Generated by: LCOV version 2.0-1