#include #include #include #include #include #include #include #include "aoc.hpp" #include "aoc/utils.hpp" #include "fmt/format.h" using namespace std::string_view_literals; using namespace aoc::types; auto part_a(std::vector> const& reports) -> void { auto const diffvec = reports | std::views::transform([](auto const& levels) { return levels | std::views::adjacent_transform<2>([](auto const& a, auto const& b) { return b - a; }) | std::ranges::to(); }) | std::ranges::to(); auto answer = diffvec | std::views::filter([](auto const& levels) { auto const n = std::ranges::all_of(levels, [](auto v) { return v < 0; }); auto const p = std::ranges::all_of(levels, [](auto v) { return v > 0; }); auto const c = std::ranges::all_of(levels, [](auto v) { return std::abs(v) > 0 && std::abs(v) <= 3; }); return (n || p) && c; }); auto const sum = std::ranges::distance(answer); fmt::print("Part A: {}\n", sum); } auto part_b(std::vector> const& reports) -> void { auto const diffvec = reports | std::views::transform([](auto const& levels) { return levels | std::views::adjacent_transform<2>([](auto const& a, auto const& b) { return b - a; }) | std::ranges::to(); }) | std::ranges::to(); auto const test_rule = [](std::vector const& levels) { auto const n = std::ranges::all_of(levels, [](auto v) { return v < 0; }); auto const p = std::ranges::all_of(levels, [](auto v) { return v > 0; }); auto const c = std::ranges::all_of(levels, [](auto v) { return std::abs(v) > 0 && std::abs(v) <= 3; }); return (n || p) && c; }; auto nochange = diffvec | std::views::filter(test_rule); auto unmet = std::views::zip(reports, diffvec) | std::views::filter([](auto const& vecs) { auto const& [levels, diffs] = vecs; auto const n = std::ranges::all_of(diffs, [](auto v) { return v < 0; }); auto const p = std::ranges::all_of(diffs, [](auto v) { return v > 0; }); auto const c = std::ranges::all_of(diffs, [](auto v) { return std::abs(v) > 0 && std::abs(v) <= 3; }); return !(n || p) || !c; }) | std::views::transform([](auto const& vecs) { auto const& [levels, diffs] = vecs; return levels; }); auto refit = unmet | std::views::filter([&test_rule](auto const& levels) { std::vector vec{}; for (std::size_t i = 0; i < levels.size(); ++i) { vec = levels; vec.erase(std::begin(vec) + std::ptrdiff_t(i)); vec = vec | std::views::adjacent_transform<2>([](auto const& a, auto const& b) { return b - a; }) | std::ranges::to(); if (test_rule(vec)) return true; } return false; }); auto const first = std::ranges::distance(nochange); auto const second = std::ranges::distance(refit); fmt::print("Part B: {}\n", first + second); } auto aoc24::day02([[maybe_unused]]std::span const& args) -> std::expected { auto txtres = aoc::read_text("./dat/24/re/02.txt"); // auto txtres = aoc::read_text("./dat/24/ex/02.txt"); if (!txtres) return std::unexpected(txtres.error()); auto const txt = *txtres; auto const reports = txt | std::views::split("\n"sv) | std::views::transform([](auto const& str) { return std::string_view(str); }) | std::views::filter([](auto const& str) { return !str.empty(); }) | std::views::transform([](auto const& str) { return str | std::views::split(" "sv) | std::views::filter([](auto str) { return !str.empty(); }) | std::views::transform([](auto const& num_str) { return std::stoi(std::string(std::begin(num_str), std::end(num_str))); }) | std::ranges::to(); }) | std::ranges::to(); part_a(reports); part_b(reports); return {}; }