"prints the numbers from 1 to 100." -- you printed 0-100! ;-)
Just kidding, nice solution. Show's nicely how terrible and awesome the precompiler is.
> "prints the numbers from 1 to 100." -- you printed 0-100! ;-)
This is specifically addressed in the "Exit Portability" section:
"1. It starts at 0 instead of 1. This is just to make the output more readable by having the number encoded in the template argument (T0, T1, T2, etc) map directly to its FizzBuzz representation. If you want a strict version of FizzBuzz, just change the template specialization to terminate on '1' and return a vector<int_<1> > instead."
cat /dev/random > fizzbuzz.txt1. The candidate has a solid understanding of the template system in C++. Chances are pretty high that he has a similarly high understanding of other parts (which would come out with further discussions during the interview).
2. The candidate is a creative thinker, which is hugely important in a profession where you tend to get blocked by faulty or incomplete tools, or tools not designed for what you want to do.
3. The candidate is highly intelligent and inquisitive, which means he'll likely have more success in exploratory tasks, and he'll likely have a greater breadth and possibly depth of exposure in general.
4. The candidate can program (of course).
Yes, I program my projects in C++. No, it is not okay.
I would wager that for the vast majority of real situations you'd be better off writing that in the primary language and either bundling the precomputed result when you package your application or running it at runtime.
I'm sure there is a small class of trivial exceptions, but no non-trivial ones.
Brainfuck is Turing-complete too, you know. It's not a good language either.
template<int H=-1, typename T=void>
struct tl {
enum {head=H};
typedef T tail;
};
template<>
struct tl<> {
};
template<int N, typename Then, typename Else>
struct if_c {
typedef Then type;
};
template<typename Then, typename Else>
struct if_c<false, Then, Else> {
typedef Else type;
};
template<int N, typename SoFar>
struct is_prime {
enum {value = N%SoFar::head && is_prime<N, SoFar::tail>::value};
};
template<int N>
struct is_prime<N, tl<>> {
enum {value = 1};
};
template<int N, int C, typename SoFar=tl<>>
struct prime {
typedef typename prime<N+1, C-1, typename if_c<is_prime<N, SoFar>::value, tl<N, SoFar>, SoFar>::type>::type type;
};
template<int N, typename SoFar>
struct prime<N, 0, SoFar> {
typedef SoFar type;
};
template<int N>
struct number : prime<2, N-2> {
};
template<>
struct number<0> {
};
template<>
struct number<1> {
};
template<typename T>
struct print {
};
void main() {
typedef print<number<300>::type>::type type;
}
Here is result from Visual Studio 2005: c:\console.cpp(113) : error C2039: 'type' : is not a member of 'print<T>' with [T=tl<293,tl<283,tl<281,tl<277,tl<271,tl<269,tl<263,tl<257,tl<251,tl<241,tl<239,tl<233,tl<229,tl<227,tl<223,tl<211,tl<199,tl<197,tl<193,tl<191,tl<181,tl<179,tl<173,tl<167,tl<163,tl<157,tl<151,tl<149,tl<139,tl<137,tl<131,tl<127,tl<113,tl<109,tl<107,tl<103,tl<101,tl<97,tl<89,tl<83,tl<79,tl<73,tl<71,tl<67,tl<61,tl<59,tl<53,tl<47,tl<43,tl<41,tl<37,tl<31,tl<29,tl<23,tl<19,tl<17,tl<13,tl<11,tl<7,tl<5,tl<3,tl<2,tl<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]Wondering how this works out in g++ or other compilers?
#!/usr/bin/perl
$n = 100;
open(FH, '>touch') and print FH '' and close FH;
push @ARGV, "Fizz$_" for (1..$n/3); #push some fizz's
push @ARGV, "Buzz$_" for (1..$n/5); #push some buzz's
push @ARGV, $_ for (1..$n); #we'll sort it all out later
1 while ($_ = shift and @ARGV and !fork); #let the games begin
if (/Fizz(\d+)/) {
sleep $1 * 9;
open (FH, '>>touch') and print FH "Fizz" and close (FH);
}
elsif (/Buzz(\d+)/) {
sleep $1 * 15 + 1;
open (FH, '>>touch') and print FH "Buzz" and close (FH);
}
else {
sleep $_ * 3 + 2;
open(FH, 'touch') and @lines = <FH> and close (FH);
open(FH, '>touch') and print FH '' and close FH;
print @lines ? @lines : $_, "\n";
}
What do you think? I didn't bother cleaning up the file access. Nefarious though isn't it.Seriously, the MPL is a powerful and surprising beast but in most cases some preprocessor library like Boost.Preprocessor or Chaos is unavoidable to really make it useful. In fact, you can write this complete program with the preprocessor and I would actually prefer it (or const expression meta-programming).