Skip to content

Instantly share code, notes, and snippets.

@KrutNA
Last active September 17, 2021 19:33
Show Gist options
  • Save KrutNA/5db5b13fd0b3743da8dab7f9c21e2de4 to your computer and use it in GitHub Desktop.
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.
#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