Skip to content

Instantly share code, notes, and snippets.

@ToJans
Last active December 31, 2015 22:09
Show Gist options
  • Save ToJans/8051807 to your computer and use it in GitHub Desktop.
Save ToJans/8051807 to your computer and use it in GitHub Desktop.
My implementation of fizzbuzz in Haskell; I tried to find a functional fit for the problem...
; taken from http://elegantcode.com/2013/12/19/clojure-kata-1-fizz-buzz/
(defn fizz-buzz [number]
(let [fizz? (zero? (rem number 3))
buzz? (zero? (rem number 5))
fizz-buzz? (and fizz? buzz?)]
(cond
fizz-buzz? "fizzbuzz"
fizz? "fizz"
buzz? "buzz"
:else number)))
(defn run-fizz-buzz []
(map fizz-buzz (range 1 101)))
-- my attempt for a more elegant, functional version of fizzbuzz in haskell
fizzbuzz n = zipWith max nb fb
where f = cycle ["","","fizz"]
b = cycle ["","","","","buzz"]
fb = zipWith (++) f b
nb = map show [1..n]
// Added the C#-equivalent code to show what I am doing in the Haskell code
// This is also a good showcase about why doing pure functional code in an
// imperative language might be possible, but I would not overdo it.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int n = 20;
if (args.Length > 0) int.TryParse(args[0], out n);
foreach (var str in Fizzbuzz(n))
Console.WriteLine(str);
Console.WriteLine();
foreach (var str in FizzBuzzDotNet(n))
Console.WriteLine(str);
Console.ReadKey();
}
static IEnumerable<string> Fizzbuzz(int n)
{
var f = Cycle(new string[] { "", "", "fizz" });
var b = Cycle(new string[] { "", "", "", "", "buzz" });
var fb = ZipWith(string.Concat, f, b);
var nb = Map(Show, Enumerable.Range(1, n));
return ZipWith(Max, nb, fb);
}
public static IEnumerable<T> Cycle<T>(IEnumerable<T> input)
{
while (true)
foreach (var v in input)
yield return v;
}
static IEnumerable<U> ZipWith<S, T, U>(Func<S, T, U> f, IEnumerable<S> a, IEnumerable<T> b)
{
return a.Zip(b, f);
}
static IEnumerable<V> Map<U, V>(Func<U, V> f, IEnumerable<U> col)
{
return col.Select(f);
}
static string Max(string x, string y)
{
return string.Compare(x, y) > 0 ? x : y;
}
static string Show(int x)
{
return x.ToString();
}
// This one is just to show @yreynhout is right; you can make it pretty short in C# as well
static IEnumerable<string> FizzBuzzDotNet(int n)
{
return Enumerable.Range(1,n).Select(v=>v%15>0?v%3>0?v%5>0?""+v:"buzz":"fizz":"fizzbuzz");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment