Last active
September 25, 2019 13:07
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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