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