Created
November 12, 2013 16:40
-
-
Save Yacoby/7434196 to your computer and use it in GitHub Desktop.
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> | |
#include <vector> | |
#include <functional> | |
typedef std::function<void(int)> OutputFunction; | |
typedef std::vector< OutputFunction > OutputFunctionVector; | |
template<bool c, typename T, typename F> | |
struct CondT{}; | |
template<typename T, typename F> | |
struct CondT<true, T, F> { | |
typedef T type; | |
}; | |
template<typename T, typename F> | |
struct CondT<false, T, F>{ | |
typedef F type; | |
}; | |
struct DoPrintNumT{}; | |
struct DoFizzT{}; | |
struct DoBuzzT{}; | |
struct DoFizzBuzzT{}; | |
template<int N> | |
struct FizzBuzzT{ | |
typedef typename CondT<N%15, | |
typename CondT<N%3, | |
typename CondT<N%5, | |
DoPrintNumT, | |
DoBuzzT>::type, | |
DoFizzT>::type, | |
DoFizzBuzzT>::type type; | |
}; | |
OutputFunction fizzBuzzFunction(DoPrintNumT f){ | |
return [](int n) { std::cout << n << "\n"; }; | |
} | |
OutputFunction fizzBuzzFunction(DoFizzT f){ | |
return [](int n) { std::cout << "Fizz\n"; }; | |
} | |
OutputFunction fizzBuzzFunction(DoBuzzT f){ | |
return [](int n) { std::cout << "Buzz\n"; }; | |
} | |
OutputFunction fizzBuzzFunction(DoFizzBuzzT f){ | |
return [](int n) { std::cout << "FizzBuzz\n"; }; | |
} | |
template<int N> | |
struct FizzBuzzGen{ | |
static void values(OutputFunctionVector& f){ | |
FizzBuzzGen<N-1>::values(f); | |
f[N%15] = fizzBuzzFunction(typename FizzBuzzT<N>::type()); | |
} | |
}; | |
template<> | |
struct FizzBuzzGen<0>{ | |
static void values(OutputFunctionVector& f){ | |
} | |
}; | |
void doWork(const OutputFunctionVector& v, int n){ | |
v[n%15](n); | |
} | |
void doWorkQuit(const OutputFunctionVector& v, int n){ | |
v[n%15](n); | |
exit(0); | |
} | |
std::vector< std::function<void(const OutputFunctionVector&, int)> > f = { | |
doWork, | |
doWorkQuit | |
}; | |
void rec(const OutputFunctionVector& v, int stopAt, int n){ | |
f[!(n % stopAt )](v, n); | |
rec(v, stopAt, n+1); | |
} | |
int main(int argc, char* argv[]) { | |
OutputFunctionVector output; | |
output.resize(15); | |
FizzBuzzGen<15>::values(output); | |
rec(output, std::atoi(argv[1]), 1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment