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
|
#include <filesystem>
#include <fstream>
#include <iostream>
#include <ranges>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
namespace {
vector<string>
split(const string& line, char sep)
{
istringstream strm{ line };
vector<string> parts;
for ( string part; getline(strm, part, sep); ) {
parts.emplace_back(part);
}
return parts;
}
vector<tuple<long, long>>
read_file(const filesystem::path& filename)
{
ifstream file{ filename };
string line;
getline(file, line);
vector<tuple<long, long>> ranges;
for ( const auto& part: split(line, ',') ) {
const auto range = split(part, '-');
ranges.emplace_back(stol(range.at(0)), stol(range.at(1)));
}
return ranges;
}
long
accumulate_invalids(const vector<tuple<long, long>>& ranges, const function<bool(long)>& is_invalid)
{
long sum = 0;
for ( const auto [from, to]: ranges ) {
for ( auto i = from; i <= to; ++i ) {
if ( is_invalid(i) ) {
sum += i;
}
}
}
return sum;
}
void
part1(const vector<tuple<long, long>>& ranges)
{
auto is_invalid = [](long num) {
const auto str = to_string(num);
const auto len = str.length();
if ( len % 2 == 1 ) {
return false;
}
const auto half = len / 2;
for ( size_t i = 0; i != half; ++i ) {
if ( str[i] != str[i + half] ) {
return false;
}
}
return true;
};
cout << "Part 1: " << accumulate_invalids(ranges, is_invalid) << '\n';
}
void
part2(const vector<tuple<long, long>>& ranges)
{
auto is_invalid = [](long num) {
const auto str = to_string(num);
const auto len = str.length();
const auto half = len / 2;
for ( size_t i = 1; i <= half; ++i ) {
if ( len % i != 0 ) {
continue;
}
string pattern;
while ( pattern.length() != len ) {
pattern += str.substr(0, i);
}
if ( pattern == str ) {
return true;
}
}
return false;
};
cout << "Part 2: " << accumulate_invalids(ranges, is_invalid) << '\n';
}
} // namespace
int
main()
{
auto ranges = read_file("data/day02.txt");
part1(ranges);
part2(ranges);
}
|