This started as a lunchtime conversation about interviewing. I'm a big fan of FizzBuzz as a “screening” question: it weeds out the people that shouldn't be allowed near a computer (and, after conducting several hundred interviews, I can say that there's a depressingly large number of them, especially at a company without a preliminary phone screen).
For a Scala developer, what constitutes a good FizzBuzz? Clearly, it should be based around higher-order functions, such as a map()
(and, as I don't consider myself a Scala developer, I'll leave the parentheses and dots in place):
(1 to 20).map(???)
A simple implementation might use an if
expression:
def fbi(x: Int): String = { if ((x % 15) == 0) "fizzbuzz" else if ((x % 3) == 0) "fizz" else if ((x % 5) == 0) "buzz" else s"$x" }
It gets the job done, but looks too much like Java. We need to add some Scala-specific syntax:
def fbm(x: Int): String = x match { case n if ((n % 15) == 0) => "fizzbuzz" case n if ((n % 3) == 0) => "fizz" case n if ((n % 5) == 0) => "buzz" case n => s"$n" }
You can argue whether this is better or worse. It seems to me that it just wraps the previous if
with more cruft.* As our conversation devolved, though, it led to the following implementation, which is about as far from Java as I can imagine:
object Fizz { def unapply(x: Int): Boolean = ((x % 3) == 0) } object Buzz { def unapply(x: Int): Boolean = ((x % 5) == 0) } object FizzBuzz { def unapply(x: Int): Boolean = ((x % 15) == 0) } def fbme(x: Int): String = x match { case FizzBuzz() => "fizzbuzz" case Fizz() => "fizz" case Buzz() => "buzz" case n => s"$n" }
Mind you, I don't think I'd want to hire someone who implemented FizzBuzz this way.
* You'll find a nicer match-based implementation at RosettaCode. Along with some versions that make my extractor-based implementation look sane.
No comments:
Post a Comment