Fizz, Buzz, or Fizzbuzz?

I made a new friend this week (you should totally follow @ marcopennekamp on Twitter btw) who’s a fan of programming. Well, by that I mean he is a programmer. Anyway, he introduced me to a problem known as “The fizzbuzz problem“, which is a test of coding ability for Computer Science job applicants. It’s interesting, because the problem isn’t complicated at all, yet  “99% of applicants can’t do it”. The problem is thus:

for the integers 1 to 100, print the number and then the word “fizz” if it’s a multiple of 3, the word “buzz” if it’s a multiple of 5, and “fizzbuzz” if it’s a multiple of both.

This is not a difficult thing to achieve, and any programmer worth a salary should just be able to write an iterated loop with three logic statements in. They *should* be able to. Anyway, since I’m more interested in technical computing (i.e. calculations) than computer science, I see this kind of thing all the time. I didn’t really see what all the fuss was about. I got interested in it, though, when I saw the solutions on the web. All of them, all of  them were of an identical structure;

for (i=1 to i=100)

if (i is a multiple of 3 and 5) print (i and fizzbuzz)

else if (i is a multiple of 3) print (i and fizz)

else if (i is a multiple of 5) print (i and buzz)

else print (i)

Which struck me as odd. I’m a fan of Matlab, and I have to say that although that’s easy to write it’s not really interesting as such. So I made up my own problem; can I write the fizzbuzz program without writing any kind of loop?

Well, you bet I wouldn’t be writing this post if I hadn’t found a way!

Matlab has a function which is dear to my heart which is called “logical indexing”. This means that when you call an array, you can use a logical check (eg. i==1) to point to cells which satisfy the logical condition. Example: if you want to find elements of A which are integer multiples of two, you call A(mod(A,2)==0), where mod(A,2)==0 is the logical check. The problem was then finding a good way to get Matlab to write things out without using a loop. This turned out to be a lot more difficult, as Matlab is picky in how it handles strings (which are essential in this problem).

I eventually made use of a type of data structure called a “cell array” which has no restrictions on what you put in it. I won’t go into how they work, as frankly it’s boring. Let’s just jump straight to the code;

%script to demonstrate FizzBuzz

%create cell array, first column should be integers 1-100. also %spacer column
i = transpose(linspace(1,100));
c(1:100,1) = cellstr( int2str( i ) );
c(1:100,2:3) = cellstr(”);
spacer(1:100,1) = ‘ ‘;

%logic only requires two logical index functions
c(mod(i,3)==0,2) = cellstr(‘fizz’);
c(mod(i,5)==0,3) = cellstr(‘buzz’);

%string array for printing
[ char(c(:,1)) spacer char( strcat(c(:,2),c(:,3)) ) ]

So as you can see, using the character and string arrays meant that instead of writing a set of logic checks (total of four in the example I gave at the start), you can do it in two in Matlab! And all without actually using a loop. The result looks like this;

1
2
3  fizz
4
5  buzz
6  fizz
7
8
9  fizz
10  buzz
11
12  fizz
13
14
15  fizzbuzz

Which satisfies the problem nicely. I find little challenges like this fun, especially when you can write the program in as many lines as the typical iterated version (ignoring comments, it was seven, although early versions were as long as 9).

Happy coding!

Advertisements

About stoove

A physicist, researcher, and gamesman. Likes to think about the mathematics and mechanics behind all sorts of different things, and writing up the thoughts for you to read. A competent programmer, enjoys public speaking and mechanical keyboards. Has opinions which might even change from time to time.
This entry was posted in General Science, Maths and tagged , , , , , , , , , , . Bookmark the permalink.

6 Responses to Fizz, Buzz, or Fizzbuzz?

  1. Krazyito says:

    I’ve never used matlab before so I want to ask the question, if there is no loop in your program, how do you cycle through the array and call the mod functions for each?

    • stoove says:

      A good question. The key is in a feature that Matlab has which they call “logical indexing” which is a method of specifying pointers to array elements. What it means is that if you call array A with an array L which is logical values (and A and L are the same size and dimension) then the resulting handle is for the cells in array A which are at the co-ordinates at which the cells in array L have value 1 (true). For example I have an array A = [1 2 3] and L = [1 0 1] then A(L) refers to elements 1 and 3 of A, or; [1 3].

      In the code this is implemented in the lines which show the logic functions. The logic check inside c(mod(i,3)==0,2) returns an array which has length the same as i and which has boolean values which result from the logic check for each element of i. This then counts as a logical index for c, pointing to just the elements of c which correspond to values of i which are divisible by three.

      I suppose that on some level, the computer must look individually at all the array elements and decide whether each of them satisfies the logic check. However, Matlab needn’t do them all in order or even sequentially when called like this, so it’s not a classical “loop”, and it’s also a lot shorter and faster.

      Does that answer your question? 🙂

      • Krazyito says:

        So essentially matlab can just call the function simultaneously on every index of the array which is divisible by 3 or 5. Is that right?

        I also still don’t understand what the 2 is for in c(mod(i,3)==0,2). I suppose this is some sort of check since is double equals?

      • stoove says:

        Yes, that’s a fair summary. It effectively parallelises the function call, which makes it speedy. The two is just a column reference, since I’m using a 2D array there. 🙂

      • Krazyito says:

        Perfect sense. Thanks.

        Makes me wonder what other ordinary languages have this capability.

      • stoove says:

        Well I know that Fortran has a FOR ALL statement, which is like a loop but isn’t sequential. Literally; for all the integers in the specified range, it carries out some operation. The order it does the operations in is unspecified, and is usually optimised upon compilation.

        Since this particular functionality is most useful when dealing with massive sets of array data, I wouldn’t be surprised to find that other languages in technical computing supported a similar feature. In Matlab, it also looks elegant, which is why I like it in particular 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s