Posted on March 10, 2008 14:45 by swilliams

Recently stumbled across some pretty neat implementations of the [in]famous FizzBuzz question in one line. I saw a python based solution, but felt it could be tweaked a little bit more:

print "\n".join(["%s" % ['fizzbuzz','fizz','buzz',i][[i%15,i%3,i%5,0].index(0)] for i in range(1,101)])

This is very clever, and not terribly hard to understand once you know the syntax. Let's break it down into its parts.

First, is the "\n".join(). Python has a join method on strings that inserts the string as the delineator of a list. Coming from a C#/Java background this seems backwards, but hey, it works.

Moving along is the list that is joined by the newline. ["%s" % expression for i in range(1,101)] means that a list of strings will be created for each integer from 1 to 101, and the value will be determined by 'expression'.

['fizzbuzz','fizz','buzz',i] is the list of the potential objects to print, according to the rules of FizzBuzz. i is the integer that will be printed if we are not going to print the other three strings.

[[i%15,i%3,i%5,0].index(0)] is where the decision to print a word is made. It creates a list on the fly to see if the current integer is a multiple of 15, 3, or 5. index(0) then gets the first position that '0' occurs. This tells the prior list which index to use. So:

When i = 1, [i%15,i%3,i%5,0].index(0) becomes [1,1,1,0].index(0), which will return 3. Then ['fizzbuzz','fizz','buzz',i][3] is 'i', which in turn prints "1".

When i = 3, [i%15,i%3,i%5,0].index(0) becomes [3,0,3,0].index(0), which will return 1 (the first position of '0'). Then ['fizzbuzz','fizz','buzz',i][1] is 'fizz', which will be printed.

What I like about this is that it is a "legitimate" one liner. Yes, you could cook up something similar in C# with gratuitous semicolons, but that violates the essence of style that C# has.


Python Bites are little bits of Python code that have helped me out in my day to day. I wouldn't necessarily build an enterprise level application out of it, but it is usually quicker for smaller scripting tasks.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Related posts

Comments

March 10. 2008 18:41

Concise, albeit unreadable.

Does Lisp count as a one-liner?

(loop for i from 1 to 101 do (print (if (= (mod i 15) 0) "FizzBuzz" (if (= (mod i 5) 0) "Buzz" (if (= (mod i 3) 0) "Fizz" i)))))
|

jpager

March 10. 2008 20:07

@ jpager:

Eh, I've been playing with Python for about a month, but I find it relatively readable... but yes it could be better. It does represent some of the expressiveness with the language though.

And Lisp... oh man. http://xkcd.com/297/
|

swilliams

March 10. 2008 20:29

@ swilliams:

Oh, I totally agree. Python has some neat little syntaxes.

And, BTW, I think this would work in C#:
public static string FizzFuzz(int n) return (n > 0 ? FizzFuzz(n-1) + "\n" : "") + (n % 15 == 0 ? "FizzFuzz" : (n % 5 == 0 ? "Fuzz" : (n % 3 == 0 ? "Fizz" : n)));
|

jpager

Add comment


 

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 20. 2008 19:49

|