Line data Source code
1 : #include "LinewiseInput.h"
2 : #include "PuzzleImpl.h"
3 :
4 : #include <re2/re2.h>
5 :
6 : #include <algorithm>
7 : #include <array>
8 : #include <numeric>
9 : #include <string_view>
10 : #include <tuple>
11 :
12 : namespace {
13 :
14 : std::array<std::string_view, 3u> constexpr colors = {"red", "green", "blue"};
15 :
16 200 : auto parseMaxNumCubes(std::string_view const gameString) {
17 200 : static RE2 const gameIdPattern(R"(Game (\d+): )");
18 200 : static RE2 const cubePattern(R"((\d+) (\w+),? ?)");
19 200 : static RE2 const semicolonPattern("; ");
20 :
21 200 : std::string_view str(gameString);
22 200 : unsigned gameId = 0;
23 200 : RE2::Consume(&str, gameIdPattern, &gameId);
24 200 : std::array<unsigned, colors.size()> maxNumCubes = {0u, 0u, 0u};
25 1080 : while (!str.empty()) {
26 880 : unsigned numCubes = 0;
27 880 : std::string_view color;
28 3152 : while (RE2::Consume(&str, cubePattern, &numCubes, &color)) {
29 2272 : auto it = std::ranges::find(colors, color);
30 2272 : if (it != colors.end()) {
31 2272 : auto const idx = std::distance(colors.begin(), it);
32 2272 : maxNumCubes[idx] = std::max(maxNumCubes[idx], numCubes);
33 2272 : }
34 2272 : }
35 880 : RE2::Consume(&str, semicolonPattern);
36 880 : }
37 :
38 200 : return std::tuple(gameId, maxNumCubes);
39 200 : }
40 :
41 100 : size_t gamePossible(std::string_view const gameString) {
42 100 : static std::array<unsigned, colors.size()> constexpr numCubesInBag = {12u, 13u, 14u};
43 100 : auto [gameId, maxNumCubesInGame] = parseMaxNumCubes(gameString);
44 :
45 100 : if (numCubesInBag[0] >= maxNumCubesInGame[0] && numCubesInBag[1] >= maxNumCubesInGame[1] &&
46 100 : numCubesInBag[2] >= maxNumCubesInGame[2])
47 57 : return gameId;
48 43 : else
49 43 : return 0u;
50 100 : }
51 :
52 100 : size_t cubePower(std::string_view const gameString) {
53 100 : auto [gameId, maxNumCubes] = parseMaxNumCubes(gameString);
54 100 : return std::reduce(maxNumCubes.begin(), maxNumCubes.end(), size_t(1), std::multiplies<>());
55 100 : }
56 :
57 : } // namespace
58 :
59 1 : template <> size_t part1<2023, 2>(std::string_view const input) {
60 1 : LinewiseInput const lines(input);
61 1 : return std::transform_reduce(lines.begin(), lines.end(), size_t(0), std::plus<>(), gamePossible);
62 1 : }
63 :
64 1 : template <> size_t part2<2023, 2>(std::string_view const input) {
65 1 : LinewiseInput const lines(input);
66 :
67 1 : return std::transform_reduce(lines.begin(), lines.end(), size_t(0), std::plus<>(), cubePower);
68 1 : }
|