Build a "BizzFuzz" program

18

3

In traditional FizzBuzz, you are asked to print the numbers from 1 to 100, but replacing every multiple of 3 with "Fizz", every multiple of 5 with "Buzz", and every multiple of both 3 and 5 (i.e. 15) with "FizzBuzz".

However, as an evil interviewer, I've invented my own twisted version of FizzBuzz, which I've decided to name BizzFuzz and give to you in a coding interview.

The rules of the game are:

  • Print each number from 1 to 100, except if the number meets one of the conditions below.

    • If the number is divisible by 4, print "Fizz".
    • If the number is divisible by 5, print "Buzz".

    • If the number is divisible by 4, but the number immediately after it is divisible by 5, print "FizzBuzz" instead of "Fizz", and print the next number regularly.

    • If the number is divisible by 5, but the number immediately after it is divisible by 4, print "BuzzFizz" instead of "Buzz", and print the next number regularly.

    • If the number is immediately before a number divisible by both 4 and 5, print "Bizz".

    • If the number is immediately after a number divisible by both 4 and 5, print "Fuzz".

    • If the number is divisible by both 4 and 5, print "BizzFuzz".

The shortest code to implement all these rules in any language wins.

Joe Z.

Posted 2013-08-16T18:11:46.040

Reputation: 30 589

Answers

4

GolfScript (83 80 chars)

(NB Howard's suggestion in the comments allows to reduce to 78 chars, but with trailing spaces on some lines).

This uses the character \0, so here it is in xxd format:

0000000: 3130 302c 7b29 2e32 3025 2742 6946 750a  100,{).20%'BiFu.
0000010: 0046 750a 0000 0046 6942 750a 0000 0000  .Fu....FiBu.....
0000020: 4669 0a00 0042 750a 0000 4669 0a00 0000  Fi...Bu...Fi....
0000030: 4275 4669 0a00 0000 0042 690a 2731 2c2f  BuFi.....Bi.'1,/
0000040: 3d32 2f27 7a7a 272a 5c6e 2b6f 727d 2f0a  =2/'zz'*\n+or}/.

and base64:

MTAwLHspLjIwJSdCaUZ1CgBGdQoAAABGaUJ1CgAAAABGaQoAAEJ1CgAARmkKAAAAQnVGaQoAAAAA
QmkKJzEsLz0yLyd6eicqXG4rb3J9Lwo=

Using ^ as a stand-in for \0, it's

100,{).20%'BiFu
^Fu
^^^FiBu
^^^^Fi
^^Bu
^^Fi
^^^BuFi
^^^^Bi
'1,/=2/'zz'*\n+or}/

Still not a particularly interesting problem.


An explanation was requested:

For values 0 to 99 inclusive:

100,{
...
}/

Increment the value (we want 1 to 100) and also find out what the incremented value is mod 20:

).20%

Split the magic string around \0 characters:

MAGIC_STRING 1,/

Take the (x mod 20)th element of that array, split it into 2-character chunks, and glue them back together with zz. Note: the string is either empty (in which case there are no chunks, so we end up with the empty string) or is a sequence of [BF][iu] prefixes followed by a newline.

=2/'zz'*

Take the other copy of the incremented number which we kept on the stack, and append a newline. Now whichever string we keep will end with a newline.

\n+

Apply a fallback operation. (This is similar to || in JavaScript or COALESCE in SQL).

or

Peter Taylor

Posted 2013-08-16T18:11:46.040

Reputation: 41 901

@minitech, typo introduced by not copy-pasting because reindenting everything is a pain in the neck. Fixed. – Peter Taylor – 2013-08-16T20:26:39.700

2reindenting everything = CTRL+K – John Dvorak – 2013-08-16T20:27:46.937

Can you explain this? – Johannes Kuhn – 2013-08-16T20:55:48.813

"Not a very interesting problem." Yeah, I had a hunch that was the case when I posted it. Still, it is a variation. – Joe Z. – 2013-08-17T00:10:47.007

It also gets more interesting as a parlour game with friends, rather than a programming challenge. Take turns trying to say the numbers in order. It's basically FizzBuzz Hardcore Edition if you don't memorize the sequence beforehand.

– Joe Z. – 2013-08-17T00:26:54.660

@PeterTaylor You can remove a few characters if you remove all zs but add a space after each string. Reinserting zz can then be done via 2/'zz'* – Howard – 2013-08-17T08:07:39.937

@Howard, I considered using 2/ but your way of doing it creates trailing spaces, and stripping those is costly. However, I see an alternative way of using it. – Peter Taylor – 2013-08-17T08:57:53.400

16

Python, 114

a='Fizz'
b='Buzz'
c='Bizz'
d='Fuzz'
e=c+d
f=a+b
g=b+a
i=1
exec"print eval('ediifiiiaibiaiigiiic'[i%20]);i+=1;"*100

Original solution (131):

f='Fizz'
for i in range(1,101):x=i%20;print('Bizz'*(x%19<1)+'Fuzz'*(x<2)or(i%4<1)*f+'Buzz'*(i%5<1or x==4)+f*(x==15)or i,i)[x%11==5]

grc

Posted 2013-08-16T18:11:46.040

Reputation: 18 565

6A truly beautiful abuse of eval – None – 2013-08-17T06:13:25.547

3

Python 2, 131

F,B,Z,I='Fizz','Buzz','Fuzz','Bizz'
for i in range(1,101):print{5:Z,19:I,i%4:B,i%5*4:F,3:B+F,16:F+B,0:I+Z,1:i,4:i}.get(i%4+i%5*4,i)

Ry-

Posted 2013-08-16T18:11:46.040

Reputation: 5 283

1You can golf this down to 154 by using a) logic short circuiting on the expression to print, b) reversing the meaning of r to calculate it in fewer characters, c) putting everything on one line: r,F,B,Z,I=1,'Fizz','Buzz','Fuzz','Bizz'\nfor i in range(1,101):a,b=i%4,i%5*4;print~-r and i or{5:Z,19:I,a:B,b:F,3:B+F,16:F+B,0:I+Z}.get(a+b,i);r=3!=a+b!=16 – Reinstate Monica – 2013-08-16T22:38:06.950

@WolframH: Thanks! I applied those with some changes to make 143. – Ry- – 2013-08-17T02:22:33.143

Ok this has me beat, impressive work. I love print 1!=a+b!=4 that is diabolical! – None – 2013-08-17T05:53:27.243

1@LegoStormtroopr: Nah. The exec/eval combo is diabolical ;) – Ry- – 2013-08-17T05:58:01.513

Yeah, that's gonna be hard to beat. I was able to squeeze and extra few form yours though by changing the print section to print{5:Z,19:I,a:B,b:F,3:B+F,16:F+B,0:I+Z,1:i,4:i}.get(a+b,i) – None – 2013-08-17T06:09:03.580

@LegoStormtroopr: Yes, indeed. Why did I do the hack? :D Thank you! – Ry- – 2013-08-17T17:24:57.293

1

An ungolfed reference implementation in Python that implements every rule literally (420 chars):

n = 1
while(n <= 100):
    if(n % 20 == 0):
        print "BizzFuzz"
    elif((n - 1) % 20 == 0):
        print "Fuzz"
    elif((n + 1) % 20 == 0):
        print "Bizz"
    elif(n % 5 == 0 and (n + 1) % 4 == 0):
        print "BuzzFizz"
        print n + 1
        n += 1
    elif(n % 4 == 0 and (n + 1) % 5 == 0):
        print "FizzBuzz"
        print n + 1
        n += 1
    elif(n % 4 == 0):
        print "Fizz"
    elif(n % 5 == 0):
        print "Buzz"
    else:
        print n
    n += 1

Joe Z.

Posted 2013-08-16T18:11:46.040

Reputation: 30 589

3Hey. You got parentheses in my Python. – Ry- – 2013-08-16T20:03:00.493

I think the IDE I was using inserted them by default. I was on a Windows machine, and trying to code using a text editor on Windows is brutal. – Joe Z. – 2013-08-17T04:44:08.037

1

Python, 150

This is derivative of minitechs (earlier) answer, but I've squeezed enough out of it to make my own:

F,B,Z,I='Fizz','Buzz','Fuzz','Bizz'
for i in range(1,101):a,b=i%4,i%5*4;print i if a+b in [1,4] else {5:Z,19:I,a:B,b:F,3:B+F,16:F+B,0:I+Z}.get(a+b,i)

The degolfed version isn't much more readable, but the r that minitech was using is only triggered if on the next iteration the sum if a,b was either 1,0 or 0,4, which is equivalent to i%4 or i%5 == 0so it was only going to appear in those circumstance. So it was possible to remove the assignment and calculation of r and derive it from the current value of i using a and b:

F,B,Z,I='Fizz','Buzz','Fuzz','Bizz'
for i in range(1,101):
 a,b=i%4,i%5*4;
 print i if a+b in [1,4] else {5:Z,19:I,a:B,b:F,3:B+F,16:F+B,0:I+Z}.get(a+b,i)

It also includes @WolframH's suggestions.

user8777

Posted 2013-08-16T18:11:46.040

Reputation:

Er, it’s not really different. Anyways, take away the spaces around [1,4] (and use (1,4) or {1,4} besides) and before {. – Ry- – 2013-08-17T02:20:57.540

Not different no, just changed enough that I thought it was worth an entry. – None – 2013-08-17T05:52:09.007

Okay, but you should golf it for whitespace. – Ry- – 2013-08-17T05:52:42.973

@minitech no worries. Cheers for the tip on the [] spacing. I was wondering why you used {} in your original answer. – None – 2013-08-17T05:56:01.880

1

R: 170 characters

a=b=1:100
o=!a%%4
i=!a%%5
w=o&i
a[o]="Fizz"
a[i]="Buzz"
a[c(i,F)&c(F,o)]="FizzBuzz"
a[c(F,i)&c(o,F)]="BuzzFizz"
a[w[-1]]="Bizz"
a[c(F,w)]="Fuzz"
a[w]="BizzFuzz"
cat(a[b])

plannapus

Posted 2013-08-16T18:11:46.040

Reputation: 8 610

1

Javascript 127 bytes

f='Fizz';b='Buzz';F='Fuzz';B='Bizz';z=n=>(n?z(n-1):0,console.log([f,b,B,F,B+F,f+b,b+f,n]["43775777071707767772"[n%20]]));z(100)

Explanation

f = 'Fizz';
b = 'Buzz';
F = 'Fuzz';
B = 'Bizz';

z = n => (
    n?z(n-1):0,  // If n is greater than 0, we keep going downwards, this happens before printing.
    console.log(
        // These are the values that we a want to print, it is
        // very important that it is written inline inside the
        // function, otherwise, we couldn't have 'n' in it
        [f,b,B,F,B+F,f+b,b+f,n][
          // The game cycles every 20 steps, so we can build a
          // look up table that we'll use to index into the other
          // table. We take advantage of implicit string -> Number
          // conversion inside the index operator, and use a
          // string instead of an array, saving 1 byte per entry
          "43775777071707767772"[n%20]])
);

z(100);

Sebastián Mestre

Posted 2013-08-16T18:11:46.040

Reputation: 71

0

Tcl, 185 chars

while {[incr i]<101} {puts [expr {$i%4?$i%5?($i-1)%4|($i-1)%5?($i+1)%4|($i+1)%5?$i:"Fuzz":"Bizz":($i-1)%4?($i+1)%4?"Buzz":"BuzzFizz":$i:($i-1)%5?($i+1)%5?$i%5?"Fizz":"FizzBuzz":$i:$i}]}

Johannes Kuhn

Posted 2013-08-16T18:11:46.040

Reputation: 7 122

Sometimes while loops can be replaced by time constructs to save bytes – sergiol – 2017-11-09T23:42:30.853