aoc24: day02b complete

This commit is contained in:
2024-12-08 22:35:49 +01:00
parent 5c692fe727
commit a1d5d359f2
14 changed files with 342 additions and 148 deletions

View File

@@ -0,0 +1,104 @@
#include <fstream>
#include <vector>
#include <algorithm>
#include <ranges>
#include <numeric>
#include <cmath>
#include <utility>
#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<std::vector<i32>> 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::vector>();
}) | std::ranges::to<std::vector>();
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<std::vector<i32>> 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::vector>();
}) | std::ranges::to<std::vector>();
auto const test_rule = [](std::vector<i32> 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<i32> 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<std::vector>();
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<char const*> const& args) -> std::expected<void, aoc::error> {
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::vector>();
}) | std::ranges::to<std::vector>();
part_a(reports);
part_b(reports);
return {};
}