Fizz Buzz in LINQ

November 1, 2017

Here's a simple implementation of FizzBuzz using LINQ:

List<string> lResults = new List<string>();
IEnumerable<int> lOneToHundred = Enumerable.Range(1, 100);
lOneToHundred.ToList().ForEach(i => lResults.Add(i % 15 == 0 ? "FizzBuzz" :
                                                         i % 3 == 0 ? "Fizz" :
                                                         i % 5 == 0 ? "Buzz" :
                                                         i.ToString()));

foreach (string lValue in lResults.Take(20))
{
    Console.WriteLine(lValue);
}

The Take(20) call here takes the first 20 rows from the result set, just to keep the output simple.

Working with Sets

A more interesting solution can be achieved by working with sets of data:

// Create the set of numbers from one to a hundred
IEnumerable<int> lRange = Enumerable.Range(1, 100);

// Create the set of numbers divisible by three, and those divisible by five
var lDivisibleByThree = lRange.Where(i => i % 3 == 0);
var lDivisibleByFive = lRange.Where(i => i % 5 == 0);

 // Create the set of numbers that aren't divisible by five or three
var lOthers = lRange.Except(lDivisibleByThree.Concat(lDivisibleByFive));

// Create the set of numbers that are divisible by five AND three
var lDivisibleByFiveAndThree = lDivisibleByThree.Intersect(lDivisibleByFive);

// Remove the numbers divisible by both five and three from the other two sets
lDivisibleByThree = lDivisibleByThree.Except(lDivisibleByFiveAndThree);
lDivisibleByFive = lDivisibleByFive.Except(lDivisibleByFiveAndThree);

// Create new set of the answer.  This is made up of a key value pair of int (1 to 100) -> answer
var lResults = lOthers.Select(n => new KeyValuePair<int, String>(n, n.ToString()))
            .Concat(lDivisibleByThree.Select(n => new KeyValuePair<int, String>(n, "Fizz")))
            .Concat(lDivisibleByFive.Select(n => new KeyValuePair<int, String>(n, "Buzz")))
            .Concat(lDivisibleByFiveAndThree.Select(n => new KeyValuePair<int, String>(n, "FizzBuzz")))
            .OrderBy(n => n.Key)  // Order by the initial number 1 to 100
            .Select(n => n.Value); // but just return the answer set, not both int and answer in a KeyValuePair

foreach (string lValue in lResults)
{
    Console.WriteLine(lValue);
}

Tags: linq fizzbuzz