AoC code coverage
Current view: top level - puzzles/2023 - Day18.cpp (source / functions) Coverage Total Hit
Test: master Lines: 96.2 % 79 76
Test Date: 2025-07-28 10:53:57 Functions: 100.0 % 7 7

            Line data    Source code
       1              : #include "Grid2d.h"
       2              : #include "LinewiseInput.h"
       3              : #include "Parsing.h"
       4              : #include "PuzzleImpl.h"
       5              : 
       6              : #include <absl/container/flat_hash_set.h>
       7              : #include <libassert/assert.hpp>
       8              : #include <re2/re2.h>
       9              : 
      10              : #include <cstdint>
      11              : #include <iostream>
      12              : #include <limits>
      13              : #include <string_view>
      14              : 
      15              : namespace {
      16              : 
      17              : using Coord = Vec2<int64_t>;
      18              : 
      19              : enum Dir : uint8_t { R = 0, D = 1, L = 2, U = 3 };
      20              : 
      21         1248 : Coord stencil(Dir dir) {
      22         1248 :   switch (dir) {
      23          303 :   case R:
      24          303 :     return {1, 0};
      25          318 :   case D:
      26          318 :     return {0, -1};
      27          321 :   case L:
      28          321 :     return {-1, 0};
      29          306 :   case U:
      30          306 :     return {0, 1};
      31            0 :   default:
      32            0 :     UNREACHABLE();
      33         1248 :   };
      34            0 : }
      35              : 
      36            1 : std::vector<std::pair<Dir, int>> parsePt1(std::string_view const input) {
      37            1 :   LinewiseInput lines(input);
      38              : 
      39            1 :   std::vector<std::pair<Dir, int>> result;
      40            1 :   result.reserve(lines.size());
      41              : 
      42            1 :   std::array<Dir, 128u> dirMap{};
      43            1 :   dirMap['R'] = R;
      44            1 :   dirMap['D'] = D;
      45            1 :   dirMap['L'] = L;
      46            1 :   dirMap['U'] = U;
      47              : 
      48            1 :   static RE2 const pattern = R"(([RLUD]) (\d+) \(#[a-z0-9]{6}\))";
      49              : 
      50          624 :   for (std::string_view line : lines) {
      51          624 :     char d = 0;
      52          624 :     int length = 0;
      53          624 :     ASSUME(RE2::FullMatch(line, pattern, &d, &length));
      54          624 :     result.emplace_back(dirMap[d], length);
      55          624 :   }
      56              : 
      57            1 :   return result;
      58            1 : }
      59              : 
      60            1 : std::vector<std::pair<Dir, int>> parsePt2(std::string_view const input) {
      61            1 :   LinewiseInput lines(input);
      62              : 
      63            1 :   std::vector<std::pair<Dir, int>> result;
      64            1 :   result.reserve(lines.size());
      65              : 
      66            1 :   static RE2 const pattern = R"([RLUD] \d+ \(#([a-z0-9]{5})([0-3])\))";
      67              : 
      68          624 :   for (std::string_view line : lines) {
      69          624 :     std::string_view lengthHexStr;
      70          624 :     int d = 0;
      71          624 :     ASSUME(RE2::FullMatch(line, pattern, &lengthHexStr, &d));
      72          624 :     result.emplace_back(Dir(d), parseHexInt<int>(lengthHexStr));
      73          624 :   }
      74              : 
      75            1 :   return result;
      76            1 : }
      77              : 
      78              : struct Horiziontal {
      79              :   int line;
      80              :   int offset;
      81              :   int length;
      82              : };
      83              : 
      84            2 : std::vector<Coord> getVertices(std::vector<std::pair<Dir, int>> const &digInstructions) {
      85              : 
      86            2 :   Coord pos{0, 0};
      87              : 
      88            2 :   std::vector<Coord> result;
      89            2 :   result.reserve(digInstructions.size());
      90              : 
      91            2 :   result.push_back(pos);
      92         1248 :   for (auto const &instruction : digInstructions) {
      93         1248 :     pos += instruction.second * stencil(instruction.first);
      94         1248 :     result.push_back(pos);
      95         1248 :   }
      96              : 
      97            2 :   return result;
      98            2 : }
      99              : 
     100            2 : size_t gaussianArea(std::vector<Coord> const &coords) {
     101            2 :   int64_t area = 0;
     102         1250 :   for (size_t i = 0; i < coords.size() - 1u; ++i) {
     103         1248 :     area += (coords[i].y() + coords[i + 1].y()) * (coords[i].x() - coords[i + 1].x());
     104         1248 :   }
     105            2 :   area = std::abs(area / 2);
     106              : 
     107            2 :   int64_t perimeter = 0;
     108         1250 :   for (size_t i = 0; i < coords.size() - 1u; ++i) {
     109         1248 :     perimeter +=
     110         1248 :         std::abs(coords[i].y() - coords[i + 1].y()) + std::abs(coords[i].x() - coords[i + 1].x());
     111         1248 :   }
     112              : 
     113            2 :   return integerCast<size_t>(area + perimeter / 2 + 1);
     114            2 : }
     115              : 
     116              : } // namespace
     117              : 
     118            1 : template <> size_t part1<2023, 18>(std::string_view const input) {
     119            1 :   auto digInstructions = parsePt1(input);
     120            1 :   auto vertices = getVertices(digInstructions);
     121            1 :   return gaussianArea(vertices);
     122            1 : }
     123              : 
     124            1 : template <> size_t part2<2023, 18>(std::string_view const input) {
     125            1 :   auto digInstructions = parsePt2(input);
     126            1 :   auto vertices = getVertices(digInstructions);
     127            1 :   return gaussianArea(vertices);
     128            1 : }
        

Generated by: LCOV version 2.0-1