Last active
September 17, 2021 19:33
-
-
Save KrutNA/5db5b13fd0b3743da8dab7f9c21e2de4 to your computer and use it in GitHub Desktop.
C++20 implementation of FizzBuzz. Compile-time, templates. No loops, ifs and others.
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 <iostream> | |
const long FIZZ_NUM = 3; | |
const long BUZZ_NUM = 5; | |
constexpr const char *FIZZ = "FIZZ"; | |
constexpr const char *BUZZ = "BUZZ"; | |
constexpr const char *FIZZ_BUZZ = "FIZZBUZZ"; | |
namespace detail | |
{ | |
template<long... digits> | |
struct to_chars { static const char value[]; }; | |
template<long... digits> | |
constexpr char to_chars<digits...>::value[] = {('0' + digits)..., 0}; | |
template<long rem, long... digits> | |
struct explode : explode<rem / 10, rem % 10, digits...> {}; | |
template<long... digits> | |
struct explode<0, digits...> : to_chars<digits...> {}; | |
} | |
template<long num> | |
struct num_to_string : detail::explode<num> {}; | |
template <long D> constexpr const char *get_fizzbuzz() { return FIZZ_BUZZ; } | |
template <long D> constexpr const char *get_fizz() { return FIZZ; } | |
template <long D> constexpr const char *get_buzz() { return BUZZ; } | |
template <long D> constexpr const char *get_none() { return num_to_string<D>::value; } | |
template <long D> concept IS_FIZZ = D % FIZZ_NUM == 0; | |
template <long D> concept IS_BUZZ = D % BUZZ_NUM == 0; | |
template <long D> concept ABOVE_ZERO = D > 0; | |
template <long S> requires ABOVE_ZERO<S> | |
class FizzBuzz { | |
const char* data[S]; | |
template <long D> requires (ABOVE_ZERO<D>) | |
constexpr void init() { | |
data[D - 1] = get<D>(); | |
init<D - 1>(); | |
} | |
template <long D> requires (!ABOVE_ZERO<D>) | |
constexpr void init() { }; | |
template<long D> requires (IS_FIZZ<D> && IS_BUZZ<D>) | |
constexpr const char *get() { return FIZZ_BUZZ; } | |
template<long D> requires IS_FIZZ<D> | |
constexpr const char *get() { return FIZZ; } | |
template<long D> requires IS_BUZZ<D> | |
constexpr const char *get() { return BUZZ; } | |
template<long D> requires (!IS_FIZZ<D> && !IS_BUZZ<D>) | |
constexpr const char *get() { return num_to_string<D>::value; } | |
public: | |
constexpr FizzBuzz() : data() { init<S>(); } | |
const char* get(const long d) const { return data[d]; } | |
}; | |
int main(int argc, char *argv[]) { | |
const long COUNT = 100; | |
constexpr FizzBuzz<COUNT> fb = FizzBuzz<COUNT>(); | |
for (auto i = 0; i < COUNT; ++i) { | |
std::cout << fb.get(i) << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment