diff --git a/2023/solvelib/18/day18.cpp b/2023/solvelib/18/day18.cpp index 1ab507e..747c9a8 100644 --- a/2023/solvelib/18/day18.cpp +++ b/2023/solvelib/18/day18.cpp @@ -192,7 +192,7 @@ struct canvas { }; block_t len_to_block(length_t p, std::vector const& mapping) { - auto it = std::find_if(mapping.begin(), mapping.end(), xmas::equals(p)); + auto it = std::partition_point(mapping.begin(), mapping.end(), xmas::less_than(p)); if (it == mapping.end()) { throw std::runtime_error(std::format("Coordinate past end of the range")); } diff --git a/2023/xmaslib/algorithm/find.hpp b/2023/xmaslib/algorithm/find.hpp deleted file mode 100644 index e83a28e..0000000 --- a/2023/xmaslib/algorithm/find.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace internal { - -auto ceil_divide(auto p, auto q) { - return p / q + (p % q != 0); -} - -template -Iterator find_sorted_single_threaded(Iterator begin, Iterator end, BinaryPredicate&& pred) { - if (end - begin <= 1) { - return begin; - } - - auto mid = begin + (end - begin) / 2; - if (pred(mid)) { - return find_sorted_single_threaded(mid, end, pred); - } - return find_sorted_single_threaded(begin, mid + 1, pred); -} - -inline std::vector> workload_distribution( - std::size_t nelems, std::size_t ncores) { - const auto elems_per_core = nelems / ncores; - const auto left_over = nelems % ncores; - - std::vector sizes(ncores, elems_per_core); - std::transform(std::execution::unseq, sizes.begin(), - sizes.begin() + static_cast(left_over), sizes.begin(), - [](auto s) { return s + 1; }); - - std::vector> boundaries(ncores); - std::size_t acc = 0; - for (std::size_t i = 0; i < ncores; ++i) { - boundaries[i] = std::make_pair(acc, acc += sizes[i]); - } - - return boundaries; -} - -template -Iterator find_sorted_parallel(Iterator begin, Iterator end, BinaryPredicate&& pred) { - const auto ncores = std::thread::hardware_concurrency(); - const auto nelems = static_cast(end - begin); - - if (nelems < ncores) { - return find_sorted_single_threaded(begin, end, std::forward(pred)); - } - - auto segments = workload_distribution(nelems, ncores); - std::vector results(ncores); - - std::transform(std::execution::seq, segments.begin(), segments.end(), results.begin(), - [=](auto s) { return find_sorted_parallel(begin + s.first, end + s.second, pred); }); - - auto jt = find_sorted_single_threaded( - results.begin(), results.end(), [=](Iterator it) { return pred(*it); }); - if (jt == results.end()) { - return end; - } - - return *jt; -} - -} - -// Given a range partitioned such that its prefix does not match the predicate, and its suffix which -// does, find_sorted returns the first entry to fail the predicate. -template -Iterator find_sorted(ExecutionPolicy&&, Iterator begin, Iterator end, BinaryPredicate&& pred) { - if constexpr (!std::is_same::iterator_category, - std::random_access_iterator_tag>::value) { - return std::find_if(begin, end, std::forward(pred)); - } - - if constexpr (std::is_same::value) { - return internal::find_sorted_single_threaded(begin, end, std::forward(pred)); - } - - if constexpr (std::is_same::value) { - return internal::find_sorted_single_threaded(begin, end, std::forward(pred)); - } - - if constexpr (std::is_same::value) { - return internal::find_sorted_parallel(begin, end, std::forward(pred)); - } - - if constexpr (std::is_same::value) { - return internal::find_sorted_parallel(begin, end, std::forward(pred)); - } - - static_assert(false, "Invalid execution policy"); -}