Don't Overthink FizzBuzz
I noticed some traffic coming to my post on
juggling from
Using FizzBuzz to Find Developers who Grok Coding. Like me, the author is having trouble with the fact that
199 out of 200 applicants for every programming job can’t write code at all. I repeat:
they can’t write any code whatsoever.
UPDATE: If you think that I just claimed that 199 out of 200 working programmers cannot code, stop immediately and either read my follow-up explaining the math, or read Joel’s article on why companies aren’t as picky as they think they are. Thank you.So the author has decided to set the bar ridiculously low. As the post says:
I’ve come to discover that people who struggle to code don’t just struggle on big problems, or even smallish problems (i.e. write a implementation of a linked list). They struggle with tiny problems.
He gives an example of a “tiny” problem that is quite suitable for a phone interview:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
One of the nice things about using a tiny problem is that anyone who has written actual code in the last six months will solve it in less than ten minutes. This is good because (a) it leaves more time for talking about important things, and (b) if the candidate can’t solve the problem you will find out right away and save yourself a lot of grief.
As you can imagine from a post like this, quite a few people have stepped forward with
creative solutions. Here’s mine:
# fizzbuzz.rb
# see http://weblog.raganwald.com/2007/01/closures-and-higher-order-functions.html
def compose *lambdas
if lambdas.empty?
lambda { nil }
elsif lambdas.size == 1
lambdas.first
else
lambda do |n|
lambdas.first.call(compose(*lambdas[1..-1]).call(n))
end
end
end
def carbonation(modulus, printable_form)
i = 0
lambda do |n|
(i = (i + 1) % modulus) == 0 && printable_form || n
end
end
print(((1..100).map
&compose(
carbonation(15, 'FizzBuzz'),
carbonation(5, 'Buzz'),
carbonation(3, 'Fizz'))).join(' '))
Right away I think you want to be careful if you ever trot a solution like this out in an
actual interview. Here are some of the things that could go wrong:
- The interviewer merely wanted to go through the motions of demonstrating you could program. Now she’s going to have to get into a discussion with you about how your solution works, which is irritating and wastes time that could have been invested more profitably on a design question;
- The interviewer might presume that you will always find the most indirect route to the destination and decide you belong in an ivory tower;
- The interviewer might not understand your solution at first glance but will make up for this by “bikeshedding” and grilling you about some minor nit like the failure modes of using
&&
and ||
instead of the if
statement or the ternary operator;
- The interviewer might have just finished The Seasoned Schemer and grill you over why your solution doesn’t use the Y Combinator to implement
compose
(snap!).
Of course, some interviewers are just looking for an excuse to talk about technical issues and will not prejudge you in any way. Speaking for myself, I would laugh if you wrote something like this out. But then again, I once worked for someone who had won the second
International Obfuscated C Contest.
Update:
Don’t Overthink the Interview EitherIf you are conducting an interview and you receive a cryptic answer, or an impossibly concise one-liner, or perhaps something like the above that is redolent of Higher Order Functions, do you embrace the candidate as a genius? Or perhaps avoid them as someone who cannot write clear, maintainable code?
I suggest the best answer is
neither. Stay on track: you asked the question for the purpose of eliminating the 199 out of 200 that have absolutely no hope of ever producing working software. You have just identified that this person is the one in two hundred applicants who can actually code. Mission accomplished. You aren’t trying to get to HIRE or NO HIRE over the phone.
Invite them in for an interview: that’s the place where you can drill down and obtain their views on professional programming. Remember, this is a
toy problem. Unless you load the question down with requirements that their answer resemble production code, why should you have any expectation that the candidate only knows one way to write software?
This is like trying to hire programmers who know both languages, FORTRAN
and COBOL.
If you do ask them for production code, don’t be surprised if the best candidates decide not to work for you: they will rightly point out that FizzBuzz is not a realistic example of a production problem.
Overall I think the best approach as an interviewer is the simplest: pose the simple question. Indicate it is a screener designed to confirm that they are the person described on the resume.
If anything, tell them that there is no need for production artifacts like documentation and unit tests, you just want working code in as little time as they are able. The no-hopers won’t get it no matter how simple the question, and the good people won’t waste a lot of time with JavaDoc and xUnit.
And then make your decision based on one objective fact:
does the code run and produce the desired output. Everything else is superfluous to the question of whether the candidate should be asked into your office for a face-to-face meeting.
Update:
a response to some of the criticism.
Labels: jobs, lispy, ruby