1+ #include < iostream>
2+ #include < filesystem>
3+ #include < fstream>
4+ #include < sstream>
5+ #include < string>
6+ #include < vector>
7+ #include < benchmark/benchmark.h>
8+ #include < iterator>
9+
10+ struct Data {
11+ std::vector<std::vector<int >> reports;
12+ };
13+
14+ bool is_monotonic (const std::vector<int >& report) {
15+ auto left = report.begin ();
16+ auto right = std::next (left, 1 );
17+ bool increasing = false ;
18+ bool decreasing = false ;
19+ while (left != report.end () && right != report.end ()) {
20+ bool _increasing = (*left < *right) && (*right > *left);
21+ bool _decreasing = (*left > *right) && (*right < *left);
22+ increasing |= _increasing;
23+ decreasing |= _decreasing;
24+
25+ if (increasing && decreasing) return false ;
26+
27+ if (_increasing || _decreasing)
28+ {
29+ int diff = std::abs (*left - *right);
30+ if (!(diff >= 1 && diff <= 3 )) {
31+ return false ;
32+ }
33+ }
34+ else {
35+ return false ;
36+ }
37+ left = std::next (left, 1 );
38+ right = std::next (right, 1 );
39+ }
40+ return true ;
41+ }
42+
43+ int part1 (const Data &data)
44+ {
45+ int safe = 0 ;
46+ for (auto & report: data.reports ) {
47+ if (is_monotonic (report)) {
48+ safe += 1 ;
49+ }
50+ else {
51+ }
52+ }
53+ return safe;
54+ }
55+
56+ int part2 (const Data &data)
57+ {
58+ return 0 ;
59+ }
60+
61+ Data parse ()
62+ {
63+ std::ifstream file (std::filesystem::path (" inputs/day2.txt" ));
64+ if (!file.is_open ())
65+ {
66+ throw std::runtime_error (" file not found" );
67+ }
68+ std::string line;
69+ Data data;
70+
71+ while (std::getline (file, line))
72+ {
73+ std::istringstream buffer (line);
74+ std::vector<int > report{std::istream_iterator<int >(buffer),
75+ std::istream_iterator<int >()};
76+ data.reports .push_back (report);
77+ }
78+
79+ return data;
80+ }
81+
82+ class BenchmarkFixture : public benchmark ::Fixture
83+ {
84+ public:
85+ static Data data;
86+ };
87+
88+ Data BenchmarkFixture::data = parse();
89+
90+ BENCHMARK_DEFINE_F (BenchmarkFixture, Part1Benchmark)
91+ (benchmark::State &state)
92+ {
93+ for (auto _ : state)
94+ {
95+ int s = part1 (data);
96+ benchmark::DoNotOptimize (s);
97+ }
98+ }
99+
100+ BENCHMARK_DEFINE_F (BenchmarkFixture, Part2Benchmark)
101+ (benchmark::State &state)
102+ {
103+ for (auto _ : state)
104+ {
105+ int s = part2 (data);
106+ benchmark::DoNotOptimize (s);
107+ }
108+ }
109+
110+ BENCHMARK_REGISTER_F (BenchmarkFixture, Part1Benchmark);
111+ BENCHMARK_REGISTER_F (BenchmarkFixture, Part2Benchmark);
112+
113+ int main (int argc, char **argv)
114+ {
115+ Data data = parse ();
116+
117+ int answer1 = 0 ;
118+ int answer2 = 0 ;
119+
120+ auto first = part1 (data);
121+ auto second = part2 (data);
122+
123+ std::cout << " Part 1: " << first << std::endl;
124+ std::cout << " Part 2: " << second << std::endl;
125+
126+ first != answer1 ? throw std::runtime_error (" Part 1 incorrect" ) : nullptr ;
127+ second != answer2 ? throw std::runtime_error (" Part 2 incorrect" ) : nullptr ;
128+
129+ for (int i = 1 ; i < argc; ++i) {
130+ if (std::string (argv[i]) == " --benchmark" ) {
131+ benchmark::Initialize (&argc, argv);
132+ benchmark::RunSpecifiedBenchmarks ();
133+ return 0 ;
134+ }
135+ }
136+ }
0 commit comments