blob: 0d3e5528aae91ed7941e6f4686c94e34bfc41ba5 (
plain)
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
|
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
using namespace std;
vector<string>
read_file(string_view filename)
{
fstream input{ filename };
vector<string> data;
for ( string line; getline(input, line); ) {
data.emplace_back(line);
}
return data;
}
vector<string>
split(const string& line, char sep)
{
stringstream input{ line };
vector<string> parts;
for ( string part; getline(input, part, sep); ) {
parts.emplace_back(part);
}
return parts;
}
template<typename Container>
Container
read_ints(const string& line)
{
Container container{};
stringstream input{ line };
for ( typename Container::value_type value; input >> value; ) {
container.emplace(value);
}
return container;
}
auto
build_data_set(string_view filename)
{
vector<unsigned long> values;
for ( const auto& line: read_file(filename) ) {
const auto cards = split(line, ':');
const auto numbers = split(cards[1], '|');
const auto winning_numbers = read_ints<set<int>>(numbers[0]);
const auto card_numbers = read_ints<set<int>>(numbers[1]);
auto count = 0U;
for ( auto number: winning_numbers ) {
if ( card_numbers.contains(number) ) {
++count;
}
}
values.emplace_back(count);
}
return values;
}
void
pass1(const vector<unsigned long>& values)
{
auto sum = 0U;
for ( auto value: values ) {
if ( value != 0 ) {
sum += (1U << (value - 1));
}
}
cout << sum << endl;
}
void
pass2(const vector<unsigned long>& values)
{
auto count = 0U;
function<void(size_t, size_t)> process = [&](size_t start, size_t end) -> void {
for ( ; start != end; ++start ) {
auto value = values[start];
++count;
process(start + 1, start + value + 1);
}
};
process(0, values.size());
cout << count << endl;
}
int
main()
{
const auto values = build_data_set("data/day04.txt");
pass1(values);
pass2(values);
}
|