Files
aoc/sol/24/day05.cpp

163 lines
6.0 KiB
C++

#include <vector>
#include <fstream>
#include <expected>
#include <system_error>
#include <ranges>
#include <string>
#include <algorithm>
#include <numeric>
#include "aoc.hpp"
#include "aoc/utils.hpp"
#include "fmt/format.h"
using namespace aoc::types;
auto part_a(std::vector<std::vector<i32>> const& rules,
std::vector<std::vector<i32>> const& updates) -> void {
// std::ranges::for_each(order_rules, [](auto const& rule) {
// std::ranges::for_each(rule, [](auto const& page) {
// fmt::print("{} ", page);
// });
// fmt::print("\n");
// });
//
// std::ranges::for_each(updates, [](auto const& update) {
// std::ranges::for_each(update, [](auto const& page) {
// fmt::print("{}, ", page);
// });
// fmt::print("\n");
// });
auto valid_updates = updates | std::views::filter([&](auto const& pages) {
return std::ranges::all_of(rules, [&](auto const& rule) {
auto const a = std::ranges::find(pages, rule[0]);
auto const b = std::ranges::find(pages, rule[1]);
return a < b || a == std::end(pages) || b == std::end(pages) || a == b;
});
});
// std::ranges::for_each(valid_updates, [](auto const& update){
// std::ranges::for_each(update, [](auto const& page) {
// fmt::print("{}, ", page);
// });
// fmt::print("\n");
// });
auto mids = valid_updates | std::views::transform([](auto const& updates) {
return *std::ranges::next(std::begin(updates), updates.size() / 2);
});
// std::ranges::for_each(mids, [](auto const& mid) {
// fmt::print("{}\n", mid);
// });
auto const sum = std::accumulate(std::begin(mids), std::end(mids), 0);
fmt::print("Part A: {}\n", sum);
}
auto part_b(std::vector<std::vector<i32>> const& rules,
std::vector<std::vector<i32>> const& updates) -> void {
auto valids = updates | std::views::filter([&](auto const& pages) {
return std::ranges::all_of(rules, [&](auto const& rule) {
auto const a = std::ranges::find(pages, rule[0]);
auto const b = std::ranges::find(pages, rule[1]);
return a < b || a == std::end(pages) || b == std::end(pages);
});
});
auto valids_mid = valids | std::views::transform([](auto const& updates) {
return *std::ranges::next(std::begin(updates), updates.size() / 2);
});
auto invalids = updates | std::views::filter([&](auto const& pages) {
return !std::ranges::all_of(rules, [&](auto const& rule) {
auto const a = std::ranges::find(pages, rule[0]);
auto const b = std::ranges::find(pages, rule[1]);
return a < b || a == std::end(pages) || b == std::end(pages);
});
});
auto invalid_rules = rules | std::views::filter([&](auto const& rule) {
return !std::ranges::all_of(invalids, [&](auto const& pages) {
auto const a = std::ranges::find(pages, rule[0]);
auto const b = std::ranges::find(pages, rule[1]);
return a < b || a == std::end(pages) || b == std::end(pages);
});
});
auto const a = std::accumulate(std::begin(valids_mid), std::end(valids_mid), 0);
(void)a;
// std::ranges::for_each(valids, [](auto const& update){
// std::ranges::for_each(update, [](auto const& page) {
// fmt::print("{}, ", page);
// });
// fmt::print("\n");
// });
// fmt::print("--------------------------------------------------------------------------------\n");
std::ranges::for_each(invalid_rules, [](auto const& rules){
std::ranges::for_each(rules, [](auto const& rule) {
fmt::print("{} ", rule);
});
fmt::print("\n");
});
std::ranges::for_each(invalids, [](auto const& update){
std::ranges::for_each(update, [](auto const& page) {
fmt::print("{}, ", page);
});
fmt::print("\n");
});
}
auto aoc24::day05([[maybe_unused]]std::span<char const*> const& args) -> std::expected<void, aoc::error> {
using namespace std::string_view_literals;
auto txtres = aoc::read_text("./dat/24/ex/05.txt");
// auto txtres = aoc::read_text("./dat/24/re/05.txt");
if (!txtres) return std::unexpected(txtres.error());
auto const txt = *txtres;
auto const not_empty = [](auto const& str) { return !str.empty(); };
auto lines = txt | std::views::split("\n"sv)
| std::views::transform([](auto const& str) { return std::string_view(str); });
auto rules_str = lines | std::views::take_while(not_empty)
| std::ranges::to<std::vector>();
auto updates_str = lines | std::views::drop_while(not_empty)
| std::views::drop(1)
| std::views::take_while(not_empty)
| std::ranges::to<std::vector>();
// fmt::print("rules:\n");
// std::ranges::for_each(rules_str, [](auto const& str) {
// fmt::print(" \"{}\"\n", str);
// });
// fmt::print("\n");
//
// fmt::print("updates:\n");
// std::ranges::for_each(updates_str, [](auto const& str) {
// fmt::print(" \"{}\"\n", str);
// });
auto order_rules = rules_str | std::views::transform([](auto const& str) {
return str | std::views::split("|"sv)
| 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>();
auto updates = updates_str | std::views::transform([](auto const& str) {
return str | std::views::split(","sv)
| 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(order_rules, updates);
part_b(order_rules, updates);
return {};
}