Line data Source code
1 : #include "LinewiseInput.h"
2 : #include "Parsing.h"
3 : #include "PuzzleImpl.h"
4 :
5 : #include <algorithm>
6 : #include <ranges>
7 : #include <string>
8 :
9 : namespace {
10 :
11 2 : std::vector<std::vector<int>> parse(std::string_view const input) {
12 2000 : return input | std::views::split('\n') | std::views::transform([](auto &&r) {
13 2000 : return r | std::views::split(' ') |
14 12824 : std::views::transform([](auto &&r) { return parseInt<int>(r); });
15 2000 : }) |
16 2 : std::ranges::to<std::vector<std::vector<int>>>();
17 2 : }
18 :
19 3942 : bool isSafe(std::ranges::input_range auto &&r) {
20 3942 : auto differences = r | std::views::pairwise_transform(std::minus{});
21 3942 : if (differences.front() > 0)
22 5988 : return std::ranges::all_of(differences, [](int const d) { return d >= 1 && d <= 3; });
23 2150 : else
24 6007 : return std::ranges::all_of(differences, [](int const d) { return d >= -3 && d <= -1; });
25 3942 : }
26 :
27 1000 : bool isSafeWithTolerance(std::ranges::input_range auto &&r) {
28 1000 : if (isSafe(r))
29 680 : return true;
30 :
31 2232 : for (int i = 0; i < std::ranges::ssize(r); ++i) {
32 1942 : auto filtered = r | std::views::enumerate |
33 28266 : std::views::filter([i](auto const &t) { return get<0>(t) != i; }) |
34 1942 : std::views::values;
35 1942 : if (isSafe(filtered))
36 30 : return true;
37 1942 : }
38 290 : return false;
39 320 : }
40 :
41 : } // namespace
42 :
43 1 : template <> std::string solvePart1<2024, 2>(std::string_view const input) {
44 1 : auto v = parse(input);
45 1000 : return std::to_string(std::ranges::count_if(v, [](auto &&r) { return isSafe(r); }));
46 1 : }
47 :
48 1 : template <> std::string solvePart2<2024, 2>(std::string_view const input) {
49 1 : auto v = parse(input);
50 1000 : return std::to_string(std::ranges::count_if(v, [](auto &&r) { return isSafeWithTolerance(r); }));
51 1 : }
|