In the NashFP group, a gang of functionally inclined Nashville area geeks recently organized by Bryan Hunter, we decided to share implementations of the classic FizzBuzz problem in various functional languages. I took my first shot in Scheme and then decided it was time to dust off my Haskell. On my first attempt I waded through the syntax enough to get something working, but it included several named functions and was clearly more code than was necessary to solve the problem. As I began to look for ways to shorten it, I remembered that a year or two ago Bryan had written a FizzBuzz implementation in Erlang that was short enough to tweet. Obviously this became my new goal.
I managed to whittle it down below 140 characters, but its readability suffered quite a bit. I thought it might be fun to dissect here bit by bit, and it might even come out shorter and more readable. I keep learning new tricks in Haskell and in the general functional approach that offer new opportunities to make my code shorter and more streamlined. You might learn some of these here, or if you have any pointers to offer me in comments, I would love to learn some from you as well.
In case you’re not familiar with FizzBuzz, it is a programming exercise in which goal is to list integers from 1 to 100, replacing those divisible by 3 with the term “Fizz,” those divisible by 5 with the term “Buzz,” and those divisible by both 3 and 5 with the term “FizzBuzz.”
For this exercise I will be using my favorite IDE, the REPL, in this case GHCI, the Glasgow Haskell Compiler Interactive.
Let’s start with the input range. We ultimately want to go from 1 to 100, but let’s start with 1 to 15 just for brevity of output while we evolve this thing.
Prelude> [1..15] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
To apply a function to each member of this list, we could use the map function or a list comprehension, which should be shorter, so let’s try that. We’ll start with a simple identity comprehension, which will do nothing for us. This step is just about making ourselves a place to do some work.
Prelude> [x | x <- [1..15]] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
Let’s try the Fizz substitution for multiples of 3. Note that the else case needs the show function to convert the integer to a string since Haskell lists must be homogenous.
Prelude> [if mod x 3 == 0 then "Fizz" else show x | x <- [1..15]] ["1","2","Fizz","4","5","Fizz","7","8","Fizz","10","11","Fizz","13","14","Fizz"]
Now for the Buzz case for multiples of 5:
Prelude> [if mod x 3 == 0 then "Fizz" else if mod x 5 == 0 then "Buzz" else show x | x <- [1..15]] ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","Fizz"]
This works up through 14, but I hate to add another case, and it’s already getting too long due to repetitive code. Under normal circumstances I might look to extract a method here, but we’re working on a one-liner, so let’s try another way. The factor mappings must be stated, and the most concise way I know is as a list of tuples.
Prelude> [(3,"Fizz"),(5,"Buzz")] [(3,"Fizz"),(5,"Buzz")]
Now we need a way to iterate through this list, run the divisibility test, and make the appropriate substitutions. First off we need to give the mapping list a chance to dance with each element in the list of integers. We can do this by tucking it into a tuple with the integer inside the comprehension.
Prelude> [(x,[(3,"Fizz"),(5,"Buzz")]) | x <- [1..15]] [(1,[(3,"Fizz"),(5,"Buzz")]),(2,[(3,"Fizz"),(5,"Buzz")]),(3,[(3,"Fizz"),(5,"Buzz")]),(4,[(3,"Fizz"),(5,"Buzz")]),(5,[(3,"Fizz"),(5,"Buzz")]),(6,[(3,"Fizz"),(5,"Buzz")]),(7,[(3,"Fizz"),(5,"Buzz")]),(8,[(3,"Fizz"),(5,"Buzz")]),(9,[(3,"Fizz"),(5,"Buzz")]),(10,[(3,"Fizz"),(5,"Buzz")]),(11,[(3,"Fizz"),(5,"Buzz")]),(12,[(3,"Fizz"),(5,"Buzz")]),(13,[(3,"Fizz"),(5,"Buzz")]),(14,[(3,"Fizz"),(5,"Buzz")]),(15,[(3,"Fizz"),(5,"Buzz")])]
The resulting list can now be used as the input for another list comprehension, where we can take another shot at applying our divisibility tests. Once again we will start with an identity comprehension just to get our terms in place before we put them to work. Since each element of the list is a 2-tuple, we can go ahead and give each member a variable, f for factor and n for name.
Prelude> [(x,[(f,n) | (f,n) <- [(3,"Fizz"),(5,"Buzz")]]) | x <- [1..15]] [(1,[(3,"Fizz"),(5,"Buzz")]),(2,[(3,"Fizz"),(5,"Buzz")]),(3,[(3,"Fizz"),(5,"Buzz")]),(4,[(3,"Fizz"),(5,"Buzz")]),(5,[(3,"Fizz"),(5,"Buzz")]),(6,[(3,"Fizz"),(5,"Buzz")]),(7,[(3,"Fizz"),(5,"Buzz")]),(8,[(3,"Fizz"),(5,"Buzz")]),(9,[(3,"Fizz"),(5,"Buzz")]),(10,[(3,"Fizz"),(5,"Buzz")]),(11,[(3,"Fizz"),(5,"Buzz")]),(12,[(3,"Fizz"),(5,"Buzz")]),(13,[(3,"Fizz"),(5,"Buzz")]),(14,[(3,"Fizz"),(5,"Buzz")]),(15,[(3,"Fizz"),(5,"Buzz")])]
Now we can add a filter to the new comprehension to get only the pairs whose factor evenly divides the integer.
Prelude> [(x,[(f,n) | (f,n) <- [(3,"Fizz"),(5,"Buzz")],mod x f == 0]) | x <- [1..15]] [(1,[]),(2,[]),(3,[(3,"Fizz")]),(4,[]),(5,[(5,"Buzz")]),(6,[(3,"Fizz")]),(7,[]),(8,[]),(9,[(3,"Fizz")]),(10,[(5,"Buzz")]),(11,[]),(12,[(3,"Fizz")]),(13,[]),(14,[]),(15,[(3,"Fizz"),(5,"Buzz")])]
That’s closer, but that comprehension is still returning the factor-name pair, and we’re only interested in the name, so let’s make that adjustment.
Prelude> [(x,[n | (f,n) <- [(3,"Fizz"),(5,"Buzz")],mod x f == 0]) | x <- [1..15]] [(1,[]),(2,[]),(3,["Fizz"]),(4,[]),(5,["Buzz"]),(6,["Fizz"]),(7,[]),(8,[]),(9,["Fizz"]),(10,["Buzz"]),(11,[]),(12,["Fizz"]),(13,[]),(14,[]),(15,["Fizz","Buzz"])]
This is starting to bear some resemblance to the result we’re after, but notice that our Fizzes and Buzzes are still coming out in lists. We might grab the head of the list, but the FizzBuzzes have two elements, and we don’t want to drop one. We need to concatenate them, which we can do with the concat function.
Prelude> [(x,concat [n | (f,n) <- [(3,"Fizz"),(5,"Buzz")],mod x f == 0]) | x <- [1..15]] [(1,""),(2,""),(3,"Fizz"),(4,""),(5,"Buzz"),(6,"Fizz"),(7,""),(8,""),(9,"Fizz"),(10,"Buzz"),(11,""),(12,"Fizz"),(13,""),(14,""),(15,"FizzBuzz")]
Now we have a list of tuples, each containing one value that we want and another that we don’t. First we’ll add a show to the x to make them the same type so we can compare them.
Prelude> [(show x,concat [n | (f,n) <- [(3,"Fizz"),(5,"Buzz")],mod x f == 0]) | x <- [1..15]]
[("1",""),("2",""),("3","Fizz"),("4",""),("5","Buzz"),("6","Fizz"),("7",""),("8",""),("9","Fizz"),("10","Buzz"),("11",""),("12","Fizz"),("13",""),("14",""),("15","FizzBuzz")]
Now that the elements in the tuples are the same type, we can use the max function to make the choice between them.
Prelude> [max (show x) (concat [n | (f,n) <- [(3,"Fizz"),(5,"Buzz")],mod x f == 0]) | x <- [1..15]] ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]
Now all that’s left to do is to remove some readability spaces to squeeze it down and blow up our input range to give us 100 inputs instead of 15.
Prelude> [max(show x)(concat[n|(f,n)<-[(3,"Fizz"),(5,"Buzz")],mod x f==0])|x<-[1..100]] ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz","16","17","Fizz","19","Buzz","Fizz","22","23","Fizz","Buzz","26","Fizz","28","29","FizzBuzz","31","32","Fizz","34","Buzz","Fizz","37","38","Fizz","Buzz","41","Fizz","43","44","FizzBuzz","46","47","Fizz","49","Buzz","Fizz","52","53","Fizz","Buzz","56","Fizz","58","59","FizzBuzz","61","62","Fizz","64","Buzz","Fizz","67","68","Fizz","Buzz","71","Fizz","73","74","FizzBuzz","76","77","Fizz","79","Buzz","Fizz","82","83","Fizz","Buzz","86","Fizz","88","89","FizzBuzz","91","92","Fizz","94","Buzz","Fizz","97","98","Fizz","Buzz"]
78 characters. Not too bad. Please let me know if you see where I could shave off some more.


[...] in Haskell – at 78 characters it’s impressive and his explanation of how it develops is a great read. 3 Comments RSS Filed under: C#, Coding Tags: C#, Coding. Twitter Weekly Updates [...]
Nice one.
Haven’t really played a lot with Haskell but that’s a nice “onelinier”.
A bit more ugly version in c#
int[] rgI = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Console.WriteLine(rgI.Aggregate(“”,(s,i)=>s+=(i%3==0?”Fizz”+(i%5==0?”Buzz”:”"):(i%5==0?”Buzz”:i.ToString()))));
Maybe not the most elegant of solutions, but hey it works.
the best I could get for the C# was 2 lines because I needed a variable, the wordiness gets me to 188 characters, I could probably write a few extension methods to get rid of the ToList() and the possibly the string.Join I might be able to turn into a .Join on the string, but you made me think, I like that.
string l;
Enumerable.Range(1, 100).Select(x => ((l = string.Join(“”,(new []{ new {v=3, n=”Fizz”}, new {v=5, n=”Buzz”}}).ToList().Select(v => x % v.v == 0 ? v.n : null))) != “” ? l : x.ToString() )).Dump();
for(int i=0;i100;printf(i%3==0?i%5==0?”Fizzbuzz”:”FIZZ”:i%5==0?”BUZZ”:”%i”,i++));
Enumerable.Range(1,100).Select(i=>i%3!=0&&i%5!=0?i.ToString():(i%3==0?”Fizz”:”")+(i%5==0?”Buzz”:”")).ToList().ForEach(Console.WriteLine);
Console.WriteLine(String.Join(” “, Enumerable.Range(1, 100).Select(i=>i%3*i%5==0?(i%3==0?”Fizz”:”")+(i%5==0?”Buzz”:”"):i.ToString())));
Oh, so it’s a C# party now, is it? Thank you all for playing.
Torving, I like the Aggregate. I don’t think that method gets the love it deserves.
Mark, yours is the shortest, but I’m afraid I might have to cry foul on stacking semicolons.
I tried, but in C# I couldn’t get it below 140 characters without treating 15 and “FizzBuzz” as a separate case. I hated to do it, because it is actually duplication of the behavior already defined by 3 and 5. But in this game I suppose brevity trumps DRYness.
Enumerable.Range(1,100).Select(i=>i%15==0?”FizzBuzz”:i%5==0?”Buzz”:i%3==0?”Fizz”:i.ToString())
This is 76 characters in ruby:
p Array.new(100){|i|i%15==0?i=”fizzbuzz”:i%5==0?i=”buzz”:i%3==0?i=”fizz”:i}
Haskell in seventy characters:
[maybe(show x)id(lookup(x`mod`5)[(3,"Fizz"),(5,"Buzz")])|x <- [1..15]]
It would be even shorter if I could use fromMaybe, but that’s not in the Prelude.
Oh yeah, that has a bug. Too early in the morning, I guess.
Python: ['Fizz'[i%3*4:]+’Buzz’[i%5*4:]or str(i)for i in range(1,101)]
73 characters:
[[n|(f,n)<-[(3,"Fizz"),(5,"Buzz"),(1,show x)],x`mod`f==0]!!0|x<-[1..100]]
65 Characters in Ruby that is still very much readable & understandable
(1..100).map{|i|i%15==0?’FizzBuzz’:i%3==0?’Fizz’:i%5==0?’Buzz’:i}
Clearly I have much to learn, while the task wasn’t too difficult, I see some excellent prose here. Thanks everyone
Scala, not a very original implementation, condensed down to 95 chars:
1 to 100 map{x=>if(x%15==0)"FizzBuzz"else if(x%3==0)"Fizz"else if(x%5==0)"Buzz"else x.toString}A more interesting implementation that uses partial functions and to which extra operations could easily be added:
val fizz: PartialFunction[Int, String] = { case x if x % 3 == 0 => "Fizz" }
val buzz: PartialFunction[Int, String] = { case x if x % 5 == 0 => "Buzz" }
val ops = Seq(fizz, buzz)
1 to 100 map { x => (ops collect { case pf if pf isDefinedAt x => pf(x) }).reduceLeftOption(_ + _) getOrElse x.toString }
Haskell version, requires MonadComprehensions:
[maybe(show x)id$["fizz"|x`rem`3==0]["buzz"|x`rem`5==0]|x<-[1..100]]
I have started a gist at github to collect the many different implementations of FizzBuzz (just for fun – I ahev added (and credited) your Haskell one-liner, if that is OK for you.
Ah, the link to the gist: https://gist.github.com/flq/5669209
Sure, Frank. Thanks.