aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--makefile3
-rw-r--r--src/day04.cpp116
2 files changed, 118 insertions, 1 deletions
diff --git a/makefile b/makefile
index 9d0c4c9..7643188 100644
--- a/makefile
+++ b/makefile
@@ -2,7 +2,8 @@ include config.mk
2 2
3all: bin/day01 \ 3all: bin/day01 \
4 bin/day02 \ 4 bin/day02 \
5 bin/day03 5 bin/day03 \
6 bin/day04
6 7
7bin/%: src/%.cpp | bin 8bin/%: src/%.cpp | bin
8 c++ $(CPPFLAGS) $^ -o $@ 9 c++ $(CPPFLAGS) $^ -o $@
diff --git a/src/day04.cpp b/src/day04.cpp
new file mode 100644
index 0000000..8afcb2c
--- /dev/null
+++ b/src/day04.cpp
@@ -0,0 +1,116 @@
1#include <cctype>
2#include <fstream>
3#include <iostream>
4#include <set>
5#include <sstream>
6#include <string>
7#include <string_view>
8#include <vector>
9
10using namespace std;
11
12vector<string>
13read_file(string_view filename)
14{
15 fstream input{ filename };
16 vector<string> data;
17
18 for ( string line; getline(input, line); ) {
19 data.emplace_back(line);
20 }
21
22 return data;
23}
24
25vector<string>
26split(const string& line, char sep)
27{
28 vector<string> parts{};
29 stringstream input{ line };
30
31 for ( string part; getline(input, part, sep); ) {
32 parts.emplace_back(part);
33 }
34
35 return parts;
36}
37
38template<typename Container>
39Container
40read_ints(const string& line)
41{
42 Container container{};
43 stringstream input{ line };
44
45 for ( typename Container::value_type value; input >> value; ) {
46 container.emplace(value);
47 }
48
49 return container;
50}
51
52vector<unsigned long>
53build_data_set()
54{
55 const auto lines = read_file("data/day04.txt");
56 vector<unsigned long> values{};
57
58 for ( const auto& line: lines ) {
59 const auto cards = split(line, ':');
60 const auto numbers = split(cards[1], '|');
61
62 const auto winning_numbers = read_ints<set<int>>(numbers[0]);
63 const auto card_numbers = read_ints<set<int>>(numbers[1]);
64
65 auto count = 0U;
66 for ( auto number: winning_numbers ) {
67 if ( card_numbers.contains(number) ) {
68 ++count;
69 }
70 }
71 values.emplace_back(count);
72 }
73
74 return values;
75}
76
77void
78pass1()
79{
80 auto sum = 0U;
81 for ( auto value: build_data_set() ) {
82 if ( value != 0 ) {
83 sum += (1U << (value - 1));
84 }
85 }
86
87 cout << sum << endl;
88}
89
90void
91pass2()
92{
93 const auto values = build_data_set();
94 auto count = 0U;
95
96 function<void(size_t, size_t)> process = [&](size_t start, size_t end) -> void {
97 for ( ; start != end; ++start ) {
98 auto value = values[start];
99
100 ++count;
101
102 process(start + 1, start + value + 1);
103 }
104 };
105
106 process(0, values.size());
107
108 cout << count << endl;
109}
110
111int
112main()
113{
114 pass1();
115 pass2();
116}