summaryrefslogtreecommitdiffstats
path: root/day02/solution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'day02/solution.cpp')
-rw-r--r--day02/solution.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/day02/solution.cpp b/day02/solution.cpp
new file mode 100644
index 0000000..e4f47b8
--- /dev/null
+++ b/day02/solution.cpp
@@ -0,0 +1,81 @@
1#include <numeric>
2#include <cassert>
3#include <print>
4#include <iostream>
5#include <vector>
6#include <ranges>
7#include <algorithm>
8#include <sstream>
9
10namespace ranges = std::ranges;
11namespace views = std::views;
12
13const auto parse_input() {
14 std::vector<std::vector<int>> result;
15 for (std::string s; std::getline(std::cin, s);) {
16 std::stringstream ss{s};
17 std::vector<int> row;
18 for (int l; ss >> l;) {
19 row.push_back(l);
20 }
21 result.push_back(row);
22 }
23 return result;
24}
25
26bool safe_report(const auto &report) {
27 assert(report.size() > 0);
28 std::vector<int> _diffs(report.size());
29 std::adjacent_difference(report.begin(), report.end(), _diffs.begin());
30
31 // The first diff is from 0 (zero) to the first layer, so we ignore it
32 const auto diffs = ranges::subrange(_diffs.begin() + 1, _diffs.end());
33 const bool ascending = std::count_if(diffs.begin(), diffs.end(), [](int d) {
34 return d > 0;
35 }) > (diffs.size() / 2);
36
37 const bool safe = ranges::all_of(diffs, [ascending](int d) {
38 const bool bounded = (1 <= std::abs(d) and std::abs(d) <= 3);
39 const bool monotonic = ((d > 0 and ascending) or (d < 0 and not ascending));
40 return monotonic and bounded;
41 });
42 return safe;
43}
44
45void part1(const auto &input) {
46 int answer{0};
47
48 for (const auto &report : input) {
49 if (safe_report(report)) {
50 ++answer;
51 }
52 }
53
54 std::println("{}", answer);
55}
56
57void part2(const auto &input) {
58 int answer{0};
59 for (const auto &report : input) {
60 if (ranges::any_of(views::iota(size_t(0), report.size()), [&report](size_t i) {
61 return safe_report(views::concat(report | views::take(i),
62 report | views::drop(i + 1)));
63 })) {
64 ++answer;
65 }
66 }
67 std::println("{}", answer);
68}
69
70int main() {
71 const auto input = parse_input();
72
73#ifndef NO_PART1
74 part1(input);
75#endif
76
77#ifndef NO_PART2
78 part2(input);
79#endif
80 return 0;
81}