Feb. 25th, 2008 06:24 pm Oh, Go Ahead. Overthink FizzBuzz. I gave the best programming interview answer I may have ever given last Friday.



The interviewer hauled out FizzBuzz and asked me to solve it. It took me a minute to stop laughing.



FizzBuzz is a brain-dead simple programming problem, used pretty much to tell if a developer has a pulse at all. It is simply this: print the numbers from 1 to 100, but print "Fizz" instead of the number if it is divisible by 3, "Buzz" if it is divisible by 5, and "FizzBuzz" if it is divisible by both. It can be a good question to spend 5-10 minutes on at the start of a technical interview, because apparently a large number of interview candidates who claim to be expert programmers turn out to be unable to solve even this simple problem. For the rest of us, Reg Braithewaite reminds you that it is an interview question, and has some good advice for you: Don't Overthink FizzBuzz.



In my case however... I thought about it for a moment, then decided to break this rule.



See, I wasn't given this problem at the beginning of an interview. I was given this question at the end of two days of interviewing. My interviewer, the CTO, had already satisfied himself that I was capable of doing the job. Now he was just interested in the experience of exploring a solution with me.



I started by trying to write a single expression to transform the output as a function of the number, got tangled up in my logic, said "Okay, I'm trying to be too clever. Let me do this the stupid way first." And I wrote a stupid solution. ( if (i%3).zero? puts "Fizz" etc.) Elapsed time? Maybe 90 seconds.



I started talking about ways to clean it up and optimize the code, but then I stopped: "You know, the code I wrote is kind of ugly but it is immediately apparent to the reader what I am trying to do. Anybody could read this and debug it. Unless there's a reason to keep going, such as a known performance bottleneck, I say we're done."



The CTO nodded and then confided in me: He had been talking about FizzBuzz with a friend of his, and they had been exchanging solutions. He had come up with four distinct solutions to the problem. I put on my best interviewer face and said, "Show me." And we spent another 20 minutes exploring his solutions, and discussing their merits.



That's when the light went on. FizzBuzz is a well-studied problem, right?



"Hang on a minute, let me drive for a second." I grabbed the keyboard and created a new file, and then wrote:

require 'fizzbuzz' puts fizzbuzz The CTO chuckled. "That would only work if you already had--"



But I was already typing again:

# if this require fails, you need to gem install fizzbuzz require 'fizzbuzz' puts fizzbuzz THIS caused the CTO to laugh out loud.



I got the job. I start tomorrow with a great team doing mostly Ruby and a bit of Rails!



But it doesn't end there. I am, if anything, unable to tell when to stop telling a joke. I registered the fizzbuzz project with RubyForge. You can indeed now install the fizzbuzz gem and run it. You're welcome. Contributions are invited.



Homepage: http://fizzbuzz.rubyforge.org

Project: http://rubyforge.org/projects/fizzbuzz/



And, of course, you can install the gem directly. :-)



Oh, and in it I included my own solution to FizzBuzz, one that I think is geniunely original. It took me 2 hours to come up with this idea¹:

(1..100).map {|i| srand(1781773465) if (i%15)==1; [i, "Fizz", "Buzz", "FizzBuzz"][rand(4)]} For the non-programmers, that makes a list of the four things you could display for each number, then picks one of them at random. If you seed the random number generator appropriately, it will make the correct choice 15 times in a row, which is when the cycle of FizzBuzz repeats itself.



¹ and about 12 hours of processor time to find the magic number 1781773465² ³.



² if you're willing to reorder the array as ["FizzBuzz", "Buzz", i, "Fizz"], you can seed the RNG with 46308667. I find this fascinating because 15 digits of fizzbuzz requires 30 bits of information, but 46308667 only requires 26 bits of storage. It's actually using rand's vast store of deterministic sequences to hide information.



³ this works with Ruby 1.8's RNG. I have tested this on Mac and Linux, but not on Win32 Ruby. YMMV. Current Mood: geeky

Current Music: If Then ... - Candice Pacheco

48 comments - Leave a comment