aboutsummaryrefslogtreecommitdiff
path: root/2023/src/day03.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2024-01-03 23:35:54 +0100
committerThomas Schmucker <ts@its1.de>2024-01-03 23:35:54 +0100
commit56e890cec0a28c0a485212ccebfaf774235a79a2 (patch)
treed9c6241a1aa247e06ab5ba2f6f11967b77d458ec /2023/src/day03.cpp
parente9a1cb0441d137d7a26cb303b7e72d3424b7392d (diff)
downloadadvent-of-code-56e890cec0a28c0a485212ccebfaf774235a79a2.tar.gz
advent-of-code-56e890cec0a28c0a485212ccebfaf774235a79a2.tar.bz2
advent-of-code-56e890cec0a28c0a485212ccebfaf774235a79a2.zip
prepare for more puzzles ... :)
Diffstat (limited to '2023/src/day03.cpp')
-rw-r--r--2023/src/day03.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/2023/src/day03.cpp b/2023/src/day03.cpp
new file mode 100644
index 0000000..b266f59
--- /dev/null
+++ b/2023/src/day03.cpp
@@ -0,0 +1,174 @@
1#include <cctype>
2#include <fstream>
3#include <iostream>
4#include <string>
5#include <string_view>
6#include <vector>
7
8using namespace std;
9
10vector<string>
11read_file(string_view filename)
12{
13 fstream input{ filename };
14 vector<string> data;
15
16 for ( string line; getline(input, line); ) {
17 data.emplace_back(line);
18 }
19
20 return data;
21}
22
23bool
24is_digit(char chr)
25{
26 return std::isdigit(static_cast<unsigned char>(chr)) != 0;
27}
28
29vector<tuple<size_t, size_t>>
30positions(size_t row, size_t col)
31{
32 return {
33 { row - 1, col - 1 },
34 { row - 0, col - 1 },
35 { row + 1, col - 1 },
36
37 { row - 1, col },
38 { row + 1, col },
39
40 { row - 1, col + 1 },
41 { row - 0, col + 1 },
42 { row + 1, col + 1 },
43 };
44}
45
46void
47part1() // NOLINT
48{
49 auto lines = read_file("data/day03.txt");
50
51 auto is_symbol = [&lines](size_t row, size_t col) -> bool {
52 static const string symbols{ "*#+$%=-@&/" };
53
54 if ( row >= lines.size() || col >= lines[row].size() ) {
55 return false;
56 }
57
58 auto symbol = lines[row][col];
59
60 return symbols.find(symbol) != string::npos;
61 };
62
63 auto bordering = [&is_symbol](size_t row, size_t col) -> bool {
64 bool result = false;
65
66 for (const auto& position: positions(row, col)) {
67 result |= is_symbol(get<0>(position), get<1>(position));
68 }
69
70 return result;
71 };
72
73 auto sum = 0;
74 for ( size_t row = 0; row != lines.size(); ++row ) {
75 const auto& line = lines[row];
76
77 string::size_type start = 0;
78 while ( start != line.size() ) {
79 while ( start != line.size() && !is_digit(line[start]) ) {
80 ++start;
81 }
82
83 auto end = start;
84 while ( end != line.size() && is_digit(line[end]) ) {
85 ++end;
86 }
87
88 if ( start != end ) {
89 auto result = false;
90
91 for ( auto col = start; col != end; ++col ) {
92 result |= bordering(row, col);
93 }
94
95 if ( result ) {
96 sum += stoi(line.substr(start, end - start));
97 }
98
99 start = end;
100 }
101 }
102 }
103 cout << sum << endl;
104}
105
106void
107part2() // NOLINT
108{
109 auto lines = read_file("data/day03.txt");
110
111 auto find_integer = [](vector<string>& lines, size_t row, size_t col, int& value) -> bool { // NOLINT
112 if ( row >= lines.size() || col >= lines[row].size() ) {
113 return false;
114 }
115
116 auto& line = lines[row];
117
118 if ( !is_digit(line[col]) ) {
119 return false;
120 }
121
122 // Anfang der Zahl suchen
123 auto start = col;
124 for ( ; start != 0 && is_digit(line[start - 1]); --start ) // NOLINT
125 ;
126
127 auto end = col;
128 for ( ; end != line.size() && is_digit(line[end]); ++end ) // NOLINT
129 ;
130
131 value = stoi(line.substr(start, end - start));
132
133 for ( ; start != end; ++start ) {
134 line[start] = '.';
135 }
136
137 return true;
138 };
139
140 auto sum = 0;
141 for ( size_t row = 0; row != lines.size(); ++row ) {
142 const auto& line = lines[row];
143
144 auto col = line.find('*');
145 while ( col != string::npos ) {
146 vector<int> values;
147
148 auto lines_copy{ lines };
149
150 for ( const auto& position: positions(row, col) ) {
151 auto value = 0;
152
153 if ( find_integer(lines_copy, get<0>(position), get<1>(position), value) ) {
154 values.emplace_back(value);
155 }
156 }
157
158 if ( values.size() == 2 ) {
159 auto ratio = values[0] * values[1];
160 sum += ratio;
161 }
162
163 col = line.find('*', col + 1);
164 }
165 }
166 cout << sum << endl;
167}
168
169int
170main()
171{
172 part1();
173 part2();
174}