LCOV - code coverage report
Current view: top level - 16 - b.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 56 56
Test Date: 2025-10-12 18:20:59 Functions: 100.0 % 1 1
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 92.5 % 40 37

             Branch data     Line data    Source code
       1                 :             : #include <iostream>
       2                 :             : #include <vector>
       3                 :             : #include <fstream>
       4                 :             : #include <tuple>
       5                 :             : #include <queue>
       6                 :             : #include <set>
       7                 :             : #include <string>
       8                 :             : #include <limits>
       9                 :             : #include <cstdint>
      10                 :             : #include <array>
      11                 :             : 
      12                 :             : using namespace std;
      13                 :             : 
      14                 :             : constexpr array<int_fast8_t, 4> dx{1, 0, -1, 0};
      15                 :             : constexpr array<uint_fast8_t, 2> turnOffsets{1, 3};
      16                 :             : 
      17                 :           2 : int main() {
      18                 :           2 :   ifstream input("input.txt");
      19         [ +  + ]:           2 :   if (!input) {
      20                 :           1 :     cerr << "Error: Could not open input file.\n";
      21                 :           1 :     return 1;
      22                 :             :   }
      23                 :           1 :   vector<string> grid;
      24                 :           1 :   pair<uint_fast16_t, uint_fast16_t> start;
      25                 :           1 :   pair<uint_fast16_t, uint_fast16_t> end;
      26                 :             : 
      27         [ +  + ]:         142 :   for (string line; getline(input, line); grid.push_back(std::move(line))) {
      28         [ +  + ]:       20022 :     for (uint_fast8_t col = 0; col < line.size(); ++col) {
      29         [ +  + ]:       19881 :       if (line[col] == 'S') {
      30                 :           1 :         start = {grid.size(), col};
      31                 :             :       }
      32                 :             :     }
      33                 :           1 :   }
      34                 :             : 
      35                 :           1 :   uint_fast32_t rows = grid.size();
      36                 :           1 :   uint_fast32_t cols = grid[0].size();
      37                 :           1 :   vector visited(rows, vector(cols, vector(4, numeric_limits<uint_fast32_t>::max())));
      38                 :           2 :   vector<vector<vector<vector<tuple<int, int, int>>>>> predecessors(rows, vector<vector<vector<tuple<int, int, int>>>>(cols, vector<vector<tuple<int, int, int>>>(4)));
      39                 :             : 
      40                 :           1 :   priority_queue<tuple<uint_fast32_t, uint_fast16_t, uint_fast16_t, uint_fast8_t>, vector<tuple<uint_fast32_t, uint_fast16_t, uint_fast16_t, uint_fast8_t>>, greater<tuple<uint_fast32_t, uint_fast16_t, uint_fast16_t, uint_fast8_t>>> pq;
      41                 :             :     
      42                 :           1 :   pq.emplace(0, start.first, start.second, 0);
      43                 :           1 :   visited[start.first][start.second][0] = 0;
      44                 :             : 
      45         [ +  - ]:       40578 :   while (!pq.empty()) {
      46                 :       40578 :     auto [cost, r, c, dir] = pq.top();
      47                 :       40578 :     pq.pop();
      48                 :             : 
      49         [ +  + ]:       40578 :     if (grid[r][c] == 'E') {
      50                 :           1 :       end = {r, c};
      51                 :           1 :       break;
      52                 :             :     }
      53                 :       40577 :     uint_fast16_t nr = r + dx[(dir + 3) & 3];
      54                 :       40577 :     if (uint_fast16_t nc = c + dx[dir];
      55   [ +  -  +  -  :       40577 :         nr >= 0 && nc >= 0 && nr < rows && nc < cols && grid[nr][nc] != '#') {
             +  +  +  + ]
      56         [ +  + ]:       21004 :       if (cost + 1 < visited[nr][nc][dir]) {
      57                 :       11046 :         visited[nr][nc][dir] = cost + 1;
      58                 :       11046 :         pq.emplace(cost + 1, nr, nc, dir);
      59                 :       11046 :         predecessors[nr][nc][dir] = {{r, c, dir}};
      60         [ +  + ]:        9958 :       } else if (cost + 1 == visited[nr][nc][dir]) {
      61                 :         216 :         predecessors[nr][nc][dir].emplace_back(r, c, dir);
      62                 :             :       }
      63                 :             :     }
      64                 :             : 
      65         [ +  + ]:      121731 :     for (uint_fast8_t offset : turnOffsets) {
      66                 :       81154 :       uint_fast8_t newDir = (dir + offset) & 3;
      67         [ +  + ]:       81154 :       if (cost + 1000 < visited[r][c][newDir]) {
      68                 :       29599 :         visited[r][c][newDir] = cost + 1000;
      69                 :       29599 :         pq.emplace(cost + 1000, r, c, newDir);
      70                 :       29599 :         predecessors[r][c][newDir] = {{r, c, dir}};
      71         [ +  + ]:       51555 :       } else if (cost + 1000 == visited[r][c][newDir]) {
      72                 :        9353 :         predecessors[r][c][newDir].emplace_back(r, c, dir);
      73                 :             :       }
      74                 :             :     }
      75                 :             :   }
      76                 :             : 
      77                 :           1 :   set<pair<uint_fast16_t, uint_fast16_t>> unique_tiles;
      78                 :           1 :   queue<tuple<uint_fast16_t, uint_fast16_t, uint_fast8_t>> q;
      79                 :             :     
      80         [ +  + ]:           5 :   for (uint_fast8_t dir = 0; dir < 4; dir++) {
      81         [ +  + ]:           4 :     if (visited[end.first][end.second][dir] != numeric_limits<uint_fast32_t>::max()) {
      82                 :           1 :       q.emplace(end.first, end.second, dir);
      83                 :             :     }
      84                 :             :   }
      85                 :             : 
      86         [ +  + ]:        2842 :   while (!q.empty()) {
      87                 :        2841 :     auto [row, col, direction] = q.front();
      88                 :        2841 :     q.pop();
      89                 :        2841 :     unique_tiles.emplace(row, col);
      90                 :             : 
      91         [ +  + ]:        5681 :     for (const auto& predecessor : predecessors[row][col][direction]) {
      92                 :        2840 :       q.emplace(predecessor);
      93                 :             :     }
      94                 :             :   }
      95                 :             : 
      96                 :           1 :   cout << unique_tiles.size() << endl;
      97         [ +  + ]:           3 : }
        

Generated by: LCOV version 2.0-1