Skip to content

Instantly share code, notes, and snippets.

@RomeoV
Last active September 25, 2019 13:07
Show Gist options
  • Save RomeoV/ba110b7eb113f52c2c0ed70aa3d095fa to your computer and use it in GitHub Desktop.
Save RomeoV/ba110b7eb113f52c2c0ed70aa3d095fa to your computer and use it in GitHub Desktop.
Solves the second ProjectEuler problem completely during compile time. Uses C++20 features (currently only in gcc head).
#include <array>
using uint = unsigned int;
constexpr uint fib(std::size_t n) {
return (n <=1)? 1 : fib(n-1) + fib(n-2);
}
template<typename T>
constexpr bool predicament(T num) {
return num < 4000000 and num%2 == 0;
}
// This is basically constexpr std::accumulate with a condition
template<typename T, std::size_t N, class Function>
constexpr T compile_time_accumulator(std::array<T, N> const &A, Function&& f) {
T sum(T(0));
for(std::size_t i = 0; i < N; ++i) {
if (f(A[i]))
sum += A[i];
}
return sum;
}
// This is basically constexpr std::iota
template<typename T, std::size_t N, class Function, std::size_t... I>
constexpr std::array<T, N> make_array(Function&& func, std::index_sequence<I...>) {
return { func(I)... };
}
template<typename T, std::size_t N, class Function>
constexpr std::array<T, N> make_array(Function&& func) {
return make_array<T,N>(std::forward<Function>(func), std::make_index_sequence<N>());
}
int main()
{
constexpr auto N = 100;
constexpr auto arr = make_array<uint, N>(fib);
static_assert(compile_time_accumulator(arr, predicament<decltype(arr)::value_type>) == 4613732);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment