Skip to content

Instantly share code, notes, and snippets.

@kenpusney
Created April 25, 2019 05:33
Show Gist options
  • Select an option

  • Save kenpusney/dbaf8fc86ebbb35ad392c8d72c4d01a2 to your computer and use it in GitHub Desktop.

Select an option

Save kenpusney/dbaf8fc86ebbb35ad392c8d72c4d01a2 to your computer and use it in GitHub Desktop.

Revisions

  1. kenpusney created this gist Apr 25, 2019.
    57 changes: 57 additions & 0 deletions fizzbuzz.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    #include <string>

    using namespace std;

    constexpr char to_char(unsigned x)
    {
    return x % 10 + '0';
    }

    template <unsigned... digits>
    constexpr char to_chars[] = {to_char(digits)..., '\0'};

    template <unsigned rem, unsigned... digits>
    constexpr string_view explode = explode<rem / 10, rem % 10, digits...>;

    template <unsigned... digits>
    constexpr string_view explode<0, digits...> = {to_chars<digits...>};

    template <unsigned num>
    constexpr string_view string_of = explode<num>;

    constexpr bool can_divide(unsigned x, unsigned y)
    {
    return x % y == 0;
    }

    constexpr bool contains(string_view x, char m)
    {
    return x.find(m) != x.npos;
    }

    template <unsigned x, unsigned y>
    constexpr bool can_divide_or_contains = can_divide(x, y) || contains(string_of<x>, to_char(y));

    template <unsigned x, bool for3, bool for5>
    constexpr string_view fizzbuzz_of_impl = string_of<x>;

    template <unsigned x>
    constexpr string_view fizzbuzz_of_impl<x, true, false> = "Fizz";
    template <unsigned x>
    constexpr string_view fizzbuzz_of_impl<x, false, true> = "Buzz";
    template <unsigned x>
    constexpr string_view fizzbuzz_of_impl<x, true, true> = "FizzBuzz";

    template <unsigned x>
    constexpr string_view fizzbuzz_of =
    fizzbuzz_of_impl<x, can_divide_or_contains<x, 3>, can_divide_or_contains<x, 5>>;

    int main()
    {
    static_assert(fizzbuzz_of<1> == "1");
    static_assert(fizzbuzz_of<3> == "Fizz");
    static_assert(fizzbuzz_of<5> == "Buzz");
    static_assert(fizzbuzz_of<15> == "FizzBuzz");
    static_assert(fizzbuzz_of<2> == "2");
    static_assert(fizzbuzz_of<51> == "FizzBuzz");
    }