1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#include <filesystem>
#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
namespace {
using Grid = vector<vector<long>>;
using Ops = vector<char>;
vector<string>
read_file(const filesystem::path& filename)
{
ifstream file{ filename };
vector<string> lines;
for ( string line; getline(file, line); ) {
lines.emplace_back(line);
}
return lines;
}
Ops
read_ops(const string& line)
{
stringstream strm{ line };
Ops ops;
for ( char chr{}; strm >> chr; ) {
ops.emplace_back(chr);
}
return ops;
}
Ops
extract_ops(vector<string>& lines)
{
auto ops = read_ops(lines.back());
ranges::reverse(ops);
lines.pop_back();
return ops;
}
template<typename Matrix>
Matrix
rotateLeft90(const Matrix& matrix)
{
using Row = typename Matrix::value_type;
using T = typename Row::value_type;
if ( matrix.empty() ) {
return Matrix{};
}
const size_t rows = matrix.size();
const size_t cols = matrix[0].size();
Matrix result(cols, Row(rows, T{}));
for ( size_t row = 0; row != rows; ++row ) {
for ( size_t col = 0; col != cols; ++col ) {
result[cols - 1 - col][row] = matrix[row][col];
}
}
return result;
}
long
calculate(const Grid& grid, const Ops& ops)
{
long sum = 0;
for ( size_t row = 0; row != ops.size(); ++row ) {
const auto& line = grid[row];
if ( ops[row] == '*' ) {
sum += accumulate(line.begin(), line.end(), 1L, multiplies<>());
}
else {
sum += accumulate(line.begin(), line.end(), 0L);
}
}
return sum;
}
void
part1(vector<string> lines)
{
const auto ops = extract_ops(lines);
Grid grid;
grid.reserve(lines.size());
for ( const auto& line: lines ) {
stringstream strm{ line };
vector<long> numbers;
for ( long number{}; strm >> number; ) {
numbers.emplace_back(number);
}
grid.emplace_back(numbers);
}
grid = rotateLeft90(grid);
cout << "Part 1: " << calculate(grid, ops) << '\n';
}
void
part2(vector<string> lines)
{
const auto ops = extract_ops(lines);
lines = rotateLeft90(lines);
lines.emplace_back("");
Grid grid;
vector<long> curr;
for ( const auto& line: lines ) {
if ( long number{}; sscanf(line.data(), "%ld", &number) == 1 ) {
curr.emplace_back(number);
}
else {
grid.emplace_back(curr);
curr.clear();
}
}
cout << "Part 2: " << calculate(grid, ops) << '\n';
}
} // namespace
int
main()
{
const auto lines = read_file("data/day06.txt");
part1(lines);
part2(lines);
}
|