Line data Source code
1 : #include "PuzzleImpl.h"
2 :
3 : #include "Grid2d.h"
4 : #include "IntegerCast.h"
5 : #include "LinewiseInput.h"
6 : #include "Parsing.h"
7 :
8 : #include <string_view>
9 : #include <vector>
10 :
11 : namespace {
12 :
13 1 : auto parsePt1(std::string_view const input) {
14 1 : auto lines = LinewiseInput(input);
15 1 : std::vector<uint64_t> lineNumbers = parseRange<uint64_t>(lines[0]);
16 1 : size_t const numProblems = lineNumbers.size();
17 :
18 1 : Grid2d<uint64_t> numbers(lines.size() - 1u, numProblems);
19 1001 : for (size_t i = 0; i < numProblems; ++i)
20 1000 : numbers[0, i] = lineNumbers[i];
21 4 : for (size_t lineIdx = 1; lineIdx < lines.size() - 1; ++lineIdx) {
22 3 : parseRange<uint64_t>(lines[lineIdx], lineNumbers.begin());
23 3003 : for (size_t i = 0; i < numProblems; ++i)
24 3000 : numbers[lineIdx, i] = lineNumbers[i];
25 3 : }
26 :
27 1 : std::vector<char> operations = parseRange<char>(lines[lines.size() - 1u]);
28 1 : return std::make_tuple(std::move(numbers), std::move(operations));
29 1 : }
30 :
31 : } // namespace
32 :
33 1 : template <> std::string solvePart1<2025, 6>(std::string_view const input) {
34 1 : auto const [numbers, operations] = parsePt1(input);
35 1 : uint64_t sum = 0;
36 1001 : for (int y = 0; y < numbers.ySize(); ++y) {
37 1000 : char const op = operations[y];
38 1000 : if (op == '+')
39 506 : sum +=
40 506 : std::accumulate(&numbers[0, y], &numbers[numbers.xSize(), y], uint64_t(0), std::plus{});
41 494 : else
42 494 : sum += std::accumulate(&numbers[0, y], &numbers[numbers.xSize(), y], uint64_t(1),
43 494 : std::multiplies{});
44 1000 : }
45 1 : return std::to_string(sum);
46 1 : }
47 :
48 1 : template <> std::string solvePart2<2025, 6>(std::string_view const input) {
49 1 : auto lines = LinewiseInput(input);
50 1 : std::vector<char> const operations = parseRange<char>(lines[lines.size() - 1u]);
51 1 : auto fullGrid = lines.makeCharGrid2d();
52 1 : auto numGrid = fullGrid.subgrid({0, 1}, {fullGrid.xSize(), fullGrid.ySize()}).flipY();
53 :
54 1 : uint64_t sum = 0;
55 1 : uint64_t problemNum = operations.front() == '+' ? 0u : 1u;
56 1 : size_t problemIdx = 0;
57 3728 : for (int col = 0; col < numGrid.xSize(); ++col) {
58 3727 : uint64_t num = 0;
59 18635 : for (int row = 0; row < numGrid.ySize(); ++row)
60 14908 : if (numGrid[col, row] != ' ') {
61 9425 : num = num * 10u + integerCast<uint64_t>(numGrid[col, row] - '0');
62 9425 : }
63 3727 : if (num == 0) {
64 999 : sum += problemNum;
65 999 : ++problemIdx;
66 999 : if (problemIdx < operations.size() && operations[problemIdx] == '+')
67 506 : problemNum = 0u;
68 493 : else
69 493 : problemNum = 1u;
70 2728 : } else {
71 2728 : if (operations[problemIdx] == '+')
72 1509 : problemNum += num;
73 1219 : else
74 1219 : problemNum *= num;
75 2728 : }
76 3727 : }
77 1 : sum += problemNum;
78 :
79 1 : return std::to_string(sum);
80 1 : }
|