Writing FizzBuzz

Viewed 78044

Reading the coding horror, I just came across the FizzBuzz another time.

The original post is here: Coding Horror: Why Can't Programmers.. Program?

For those who do not know: FizzBuzz is a quite popular children's game. Counting from 1 to 100, and every time a number is divisible by 3 the string "Fizz" is called, every time a number is divisible by 5 the string "Buzz" is called and every time a number is divisible by 3 and 5 both strings together "FizzBuzz" are called instead of the number.

This time, I wrote the code and it took me a minute, but there are several things that I do not like.

Here is my code:

public void DoFizzBuzz()
{
    var combinations = new Tuple<int, string>[] 
    { 
        new Tuple<int, string> (3, "Fizz"), 
        new Tuple<int, string> (5, "Buzz"), 
    };

    for (int i = 1; i <= 100; ++i)
    {
        bool found = false;

        foreach (var comb in combinations)
        {
            if (i % comb.Item1 == 0)
            {
                found = true;
                Console.Write(comb.Item2);
            }
        }

        if (!found)
        {
            Console.Write(i);
        }

        Console.Write(Environment.NewLine);
    }
}

So my questions are:

  1. How do I get rid of the bool found?
  2. Is there a better way of testing than the foreach?
47 Answers

Did anyone do this one already?

Enumerable.Range(1, 100).Select(x =>
                (x % 15 == 0) ? "FIZZBUZZ"
                : (x % 5 == 0) ? "BUZZ"
                : (x % 3 == 0) ? "FIZZ"
                : x.ToString()
                )
                .ToList()
                .ForEach(console.WriteLine);

Relatively simple solution using a for loop.

No Linq or anything - just basic shorthand if statements

for(int x=1;x<101;x++)
    Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+"");

The Linq solution which is a lot like csells (sans string interpolation) and fits on one line would be:

Enumerable.Range(1,100).ToList().ForEach(x=>Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+""));

Obviously this is a bit outside the spirit of the FizzBuzz challenge. But in my benchmark this was the fastest I could make it while single threaded and still terminating at 100. It is semi-unrolled and uses a StringBuilder. It is approximately three times faster than the standard approach.

const string FIZZ = " Fizz\n";
const string BUZZ = " Buzz\n";
const string FIZZBUZZ = " FizzBuzz\n";
    ...
var sb = new StringBuilder();
int i = 0;

while(true)
{       
    sb.Append(i+3);
    sb.Append(FIZZ);        
    sb.Append(i+5);
    sb.Append(BUZZ);        
    sb.Append(i+6);
    sb.Append(FIZZ);        
    sb.Append(i+9);
    sb.Append(FIZZ);        
    sb.Append(i+10);
    sb.Append(BUZZ);        
    if(i+12 > 100)
        break;
    sb.Append(i+12);
    sb.Append(FIZZ);    
    i+=15;
    sb.Append(i);
    sb.Append(FIZZBUZZ);
}

Console.Write(sb.ToString());

This my effort mixing Func with IEnumerable

 class Program
{
    static void Main(string[] args)
    {
        foreach (var i in FizzBuzz(100))
        {
            Console.WriteLine(i);
        }
    }

    private static IEnumerable<string> FizzBuzz(int maxvalue)
    {
        int count = 0;
        //yield return count.ToString();
        Func<int, string> FizzBuzz = (x) => ((x % 5 == 0 && x % 3 == 0) ? "FizzBuzz" : null);
        Func<int, string> Buzz = (x) => ((x % 5 == 0) ? "Buzz" : null);
        Func<int, string> Fizz = (x) => ((x % 3 == 0) ? "Fizz" : null);
        Func<int, string> Number = (x) => x.ToString();

        while (count < maxvalue)
        {
            count++;

            yield return FizzBuzz(count) ?? Buzz(count) ?? Fizz(count) ?? Number(count);
        }
    }
}

Found Stringbuilder to be the fastest.

I find this implementation the easiest to read as well.

public static void FizzBuzz() {

    StringBuilder sb = new StringBuilder();

    for (int i = 1; i <= 100; i++) {    
        if (i % 3 == 0 && i % 5 == 0) {
            sb.AppendLine($"{i} - FizzBuzz");
        } else if (i % 3 == 0) {
            sb.AppendLine($"{i} - Fizz");
        } else if (i % 5 == 0) {
            sb.AppendLine($"{i} - Buzz");
        } else {
            sb.AppendLine($"{i}");
        }
    }
    Console.WriteLine(sb);
}

straight forward solution in JavaScript

var i = 1;
while (i <= 100){
    console.log((i % 3 === 0 && i % 5 === 0) ? "FizzBuzz" : (i % 3 === 0) ? "Fizz" : (i % 5 === 0 ? "Buzz" : i));
    i++;
}

In python.....

 for i in range(0, 100) :
        a = i % 3 == 0
        b = i % 5 == 0

        if(a & b):
            print("FizzBuzz")
        elif(a):
            print("Fizz")
        elif(b):
            print("Buzz")
        else:
            print(i)
In C#...

using System;
using System.IO;
class Solution {
    static void Main(String[] args) {        
        for(int i=1;i<=100;i++)
        {                       
         string result=(i%3==0 && i%5==0) ? "FizzBuzz" : 
               (i%5==0) ? "Buzz" :
                       (i%3==0) ? "Fizz" : i.ToString();            
         Console.WriteLine(res);
        }
    }
}


In VB.NET...

Imports System
Imports System.IO

Class Solution
    Private Shared Sub Main(ByVal args As String())
        For i As Integer = 1 To 100
            Dim res As String = If((i Mod 3 = 0 AndAlso i Mod 5 = 0), "FizzBuzz", If((i Mod 5 = 0), "Buzz", If((i Mod 3 = 0), "Fizz", i.ToString())))
            Console.WriteLine(res)
        Next
    End Sub
End Class

Been answered to death but just to show another solution that answers the actual question

public static void DoFizzBuzz()
{
    var combinations = new (int multiple, string output)[]
    {
        (3, "Fizz"),
        (5, "Buzz")
    };

    for (int i = 1; i <= 100; ++i)
    {
        // Seed the accumulation function with an empty string and add any 'matches' from each combination
        var fb = combinations.Aggregate("", (c, comb) => c + (i % comb.multiple == 0 ? comb.output : ""));

        Console.WriteLine(!string.IsNullOrEmpty(fb) ? fb : $"{i}");
    }
}

The shortest answer!!!

have a read.... look i mean:

for(;++$i<101;)print($i%15?$i%3?$i%5?$i:Buzz:Fizz:FizzBuzz)."\n"

Language PHP. Enjoy.

This is an answer written in JavaScript

//returns true if modulus is zero and is reusable        
var isModulusZero = (challenge, modulator) => {
    let answer = challenge % modulator;

    if (answer == 0) {
        return true
    } else {
        return false
    }
}

var printOneToHundred = () => {
    var i = 1;

    for (i; i <= 100; i++) {

        if (isModulusZero(i, 3) && isModulusZero(i, 5)) {
            console.log('FizzBuzz')
        } else if (isModulusZero(i, 3)) {
            console.log('Fizz')
        } else if (isModulusZero(i, 5)) {
            console.log('Buzz')
        } else {
            console.log(i)
        }

    }
}

Ok - I'll bite. The LINQ heavy solution I came up with on a recent initial coding interview. Amazing how many different solutions there are to this simple problem.

public static class FizzBuzzUtils
{
    private static List<KeyValuePair<int, string>> map = new List<KeyValuePair<int, string>> {
        new KeyValuePair<int, string>(3, "Fizz"),
        new KeyValuePair<int, string>(5, "Buzz")
    };

    public static string GetValue(int i)
    {
        var matches = map.Where(kvp => i % kvp.Key == 0)
            .Select(kvp => kvp.Value)
            .ToArray();
        return matches.Length > 0 ? string.Join(string.Empty, matches) : i.ToString();
    }

    public static IEnumerable<string> Range(int start, int count)
    {
        return Enumerable.Range(start, count)
            .Select(i => GetValue(i));
    }
}

Fizz Buzz Pattern (see CachedFizzBuzz method), combined with strategy pattern.

using System;
interface IFizzBuzz
{
}
class NullFizzBuzz: IFizzBuzz
{
    public static int value;
     public override string ToString()
    {
        return value.ToString();
    }
}
class Buzz : IFizzBuzz
{
    public override string ToString()
    {
        return "Buzz";
    }
}
class Fizz: IFizzBuzz
{
    public override string ToString()
    {
        return "Fizz";
    }
}
class FizzBuzz : IFizzBuzz
{
    public override string ToString()
    {
        return "FizzBuzz";
    }
}

class FizzBuzzSolver
{
    public int Fizz { get; }
    public int Buzz { get; }
    public int Iterations { get; }
    public int FizzBuzz { get; }
    public int Quotient { get; }
    public int Remainder { get; }
    public FizzBuzzSolver(int fizz, int buzz, int iterations, int fizzbuzz, int quotient, int remainder)
    {
        Fizz = fizz;
        Buzz = buzz;
        Iterations = iterations;
        FizzBuzz = fizzbuzz;
        Quotient = quotient;
        Remainder = remainder;
    }

    internal void Solve(Action<FizzBuzzSolver> fizzBuzz)
    {
        fizzBuzz(this);
    }
}
class Program
{
    static void Main()
    {
        int fizz = 3;// int.Parse(Console.ReadLine());
        int buzz = 5;// int.Parse(Console.ReadLine());
        int iterations = 100;//int.Parse(Console.ReadLine());
        int fizzbuzz = fizz * buzz;
        int quotient = Math.DivRem(iterations, fizzbuzz, out var remainder);
        FizzBuzzSolver fb = new FizzBuzzSolver(fizz, buzz, iterations, fizzbuzz, quotient, remainder);
        switch (quotient)
        {
            case 0: fb.Solve(RemainderFizzBuzz); break;
            case 1: fb.Solve(NormalFizzBuzz);  break;
            default: fb.Solve(CachedFizzBuzz); break;
        };

        Console.Read();
    }

    private static void NormalFizzBuzz(FizzBuzzSolver fb)
    {
        for (int i = 1; i < fb.FizzBuzz; i++)
        {
            Console.WriteLine(i % fb.Fizz == 0 ? "Fizz" : i % fb.Buzz == 0 ? "Buzz" : i.ToString());
        }
        Console.WriteLine("FizzBuzz");
        for (int i = fb.FizzBuzz+1; i <= fb.Iterations; i++)
        {
            Console.WriteLine(i % fb.Fizz == 0 ? "Fizz" : i % fb.Buzz == 0 ? "Buzz" : i.ToString());
        }
    }

    private static void CachedFizzBuzz(FizzBuzzSolver fb)
    {
        var fizzbuzzArray = new IFizzBuzz[fb.FizzBuzz];

        for (int i = 0; i < fb.FizzBuzz - 1; i++)
        {
            int s = i + 1;
            if (s % fb.Fizz == 0)
            {
                fizzbuzzArray[i] = new Fizz();
                Console.WriteLine("Fizz");
            }
            else
            if (s % fb.Buzz == 0)
            {
                fizzbuzzArray[i] = new Buzz();
                Console.WriteLine("Buzz");
            }
            else
            {
                fizzbuzzArray[i] = new NullFizzBuzz();
                Console.WriteLine(s);
            }

        }
        fizzbuzzArray[fb.FizzBuzz - 1] = new FizzBuzz();
        Console.WriteLine("FizzBuzz");
        NullFizzBuzz.value = fb.FizzBuzz;
        for (int j = 1; j < fb.Quotient; j++)
        {
            for (int i = 0; i < fb.FizzBuzz; i++)
            {
                NullFizzBuzz.value++;
                Console.WriteLine(fizzbuzzArray[i]);
            }

        }
        for (int i = 0; i < fb.Remainder; i++)
        {
            NullFizzBuzz.value++;
            Console.WriteLine(fizzbuzzArray[i]);
        }
    }

    private static void RemainderFizzBuzz(FizzBuzzSolver fb)
    {
        for (int i = 1; i <= fb.Remainder; i++)
        {
            Console.WriteLine(i % fb.Fizz == 0 ? "Fizz" : i % fb.Buzz == 0 ? "Buzz" : i.ToString());
        }
    }
}

Unlike other answers here, this solution offers the possibility of easily extending it. If an interviewer were to ask you to e.g. also replace 7 with "Woof", it is easily done by adding to the map.

var map = new Dictionary<int, string>
{
    {3*5*7, "FizzBuzzWoof"}, // Optional
    {5*7, "BuzzWoof"}, // Optional
    {3*7, "FizzWoof"}, // Optional
    {3*5, "FizzBuzz"},
    {7, "Woof"},
    {5, "Buzz"},
    {3, "Fizz"},
    {1, null} // For all numbers not evenly divisible
};

var words = Enumerable
    .Range(0, 154)
    .Select(i => (i == 0 ? null : map[map.Keys.First(k => i % k == 0)]) ?? i.ToString())
    .Dump("Words");

string.Join(' ', words).Dump("Result");

Identifying all permutations, however, becomes a chore, and the more extra words are added, the more lookups will be made, but the point is to argue about understanding coding principles.

Since we are going for a generic FizzBuzz (I've seen this called Raindrops), there are a couple simple modifications to keep it generic and more readable:

  1. Renaming 'combinations' to 'primeFactors' makes it a little more descriptive
  2. Tuple field names to make accessing tuple fields more readable
  3. Linq to query the list of prime factors for the display strings we want (removing the foreach)
    • Where filters the list to factors of the current integer
    • Select transforms the matching factors into their display string
    • DefaultIfEmpty handles the 'no match found' case allowing us to remove that boolean
    • Aggregate concatenates all the matching display strings together

Try it online!

public void DoFizzBuzz()
{
    var primeFactors = new (int Factor, string Display)[]
    {
        (3, "Fizz"),
        (5, "Buzz")
    };
    for (var integer = 1; integer <= 100; ++integer)
        Console.WriteLine(primeFactors
            .Where(tuple => integer % tuple.Factor == 0)
            .Select(tuple => tuple.Display)
            .DefaultIfEmpty($"{integer}")
            .Aggregate((first, second) => $"{first}{second}")
        );
}
var min = 1;
var max = 100;

for (var i = min; i <= max; i++)
{
    if (i % 3 == 0) { goto fizz; }

checkBuzz:
    if (i % 5 == 0) { goto buzz; }
    goto writeNumber;

fizz:
    Console.Write("Fizz");
    goto checkBuzz;

buzz:
    Console.Write("Buzz");
    goto allDone;

writeNumber:
    if (i % 3 != 0) { Console.Write(i); }

allDone:
    Console.WriteLine();
}

My final approach to FizzBuzz in C#.

There are countless solutions to the FizzBuzz test but few meet my requirements in crisp clear, readable, clean and maintainable code. Let me just say what I mean with

  1. clear: isolate a task into kind of logic atoms and encapsulate them inside a type
  2. readable: think of identifier names that describe and fit to the task; format your code
  3. clean: design the members of the type with as little “noise” as possible
  4. maintainable: maybe you want to or have to extend the type in the future. think of a layout that will allow that

Here is the solution I came up with. A static class that handles the task.

My first question was: what are the possible states of FizzBuzz? Ok, either FIZZ or BUZZ, that's clear. And there is also the FIZZBUZZ state if the number can be divided by 3 and 5 at the same time. Hm, interesting. This can be regarded as a (logical) sum of FIZZ + BUZZ… Finally, the state NONE (or 0) remains if neither state fits.

As an experienced developer with old low level skills (asm), I decided to use a so-called bit vector (binary flags) to fit my task. The .NET framework also makes heavy use of these when it comes to configuration options and offers a comfortable C# language construct, the enum type. Due to public visibility, I name this enum Category to depict the possible states.

Next there are the intern FIZZ and the BUZZ functions that perform the divisibility test on the given number and return the appropriate category.

Finally the only publicly available function named “test” allows us to test a given number. It returns the number’s state as defined in Category. The trick here is, that the function calls both members fizz and buzz and combines or adds (ok, boolean ORs) their results to the proper state.

I was also experimenting with some functional approaches using lambdas but these had no advantages over the solution shown. I like to keep things simple.

Happy coding,

Tom

Download Gist: https://gist.github.com/tomschrot/da0bd69dd1e591fa3da43c1fdb3e4f85

WriteLine ("Final FizzBuzz in C#\nby Tom Schröter\n");

for (int n = 1; n <= 100; n++)
    WriteLine ("{0,3}: {1}", n, FizzBuzz.test(n));

WriteLine ($"\r\nOK @ {DateTime.Now}");

static class FizzBuzz
{
    public enum Category: uint { NONE = 0, FIZZ = 0b0001, BUZZ = 0b0010, FITZBUZZ = 0b0011 };

    private static Category fizz (int n) => n % 3 == 0 ? Category.FIZZ : Category.NONE;
    private static Category buzz (int n) => n % 5 == 0 ? Category.BUZZ : Category.NONE;

    public  static Category test (int n) => fizz (n) | buzz (n);
}

The amount of people here using the most complex and over the top ways to do this very simple task hurts my head. This problem does not need three if statements, something the OP did get right. This was my quick solution:

    for (int i = 1; i<=100; ++i) {
        string printValue = string.Empty;
        printValue += (i%3==0)? "Fizz" : string.Empty;
        printValue += (i%5==0)? "Buzz" : string.Empty;
        if (printValue != string.Empty) Console.WriteLine(printValue);
    }

It avoids using nested loops, there are only two situations to check and storing them in a tuple array is adding complexity to the code with little if any performance or readability gain, but otherwise you had a unique take on it. Im interested if you have programmed in another language, since you used ++i over i++ in your for loop, both work the same in a for loop but the pre increment is slightly more performant, I didn't learn this for a very long time.

As for my code, you can technically just put the condition check into an if statnemt to avoid adding string.Empty to print value if you so wish, but I like the look of this format. You can also more than likely do it in only 3 or so lines, but it gets hard to read.

Now for anyone who has or wants to provide a solution of their own, you can easily simplify this down and use a lookup table or something like that, but the task that was asked was to check EACH number and print a value based on its divisibility. As a programmer, its important to focus on what was asked, not what you think is better. Too many times we will get caught up in trying to outdo ourselves or each other and end up producing something that is either-

  • A- Unreadable
  • B- Unextendible
  • C- Incorrect
  • D- Not what the person actually asked for

As of C# 8.0 you can use tuple pattern matching to solve FizzBuzz.

foreach (var item in Enumerable.Range(1, 100).Select(FizzBuzz))
{
    Console.WriteLine(item);
}

static string FizzBuzz(int number)
{
    return (number % 3, number % 5) switch
    {
        (0, 0) => "FizzBuzz",
        (0, _) => "Fizz",
        (_, 0) => "Buzz",
        _ => number.ToString(),
    };
}

Sample based upon this answer.

Related