30
\$\begingroup\$

Once upon a time, I was reading this question/answer on Quora

Are there really programmers with computer science degrees who cannot pass the FizzBuzz test

This code is given as the obvious answer

for i in range(1, 100):
    if i % 3 == 0 and i % 5 == 0:
        print "FizzBuzz"
    elif i % 3 == 0:
        print "Fizz"
    elif i % 5 == 0:
        print "Buzz"
    else:
        print i

Of course FizzBuzz has been golfed to death, but that is not what this question is about. You see, in the comments, someone mentions that this obvious answer is great since it's easy to add extra conditions such as print "Jazz" for multiples of 4. (I don't agree. Extending this scheme requires O(2**n) lines of code.)

Your challenge is to write the most beautiful version of FizzJazzBuzz as judged by your peers.

Some things for voters to consider:

  1. DRY
  2. Efficiency of division/modulus operations

Many of the answers on Quora were using Python, but there is no such language restriction here.

I'll accept the answer with the most votes one month from now

Sample output:

1
2
Fizz
Jazz
Buzz
Fizz
7
Jazz
Fizz
Buzz
11
FizzJazz
13
14
FizzBuzz
Jazz
17
Fizz
19
JazzBuzz
Fizz
22
23
FizzJazz
Buzz
26
Fizz
Jazz
29
FizzBuzz
31
Jazz
Fizz
34
Buzz
FizzJazz
37
38
Fizz
JazzBuzz
41
Fizz
43
Jazz
FizzBuzz
46
47
FizzJazz
49
Buzz
Fizz
Jazz
53
Fizz
Buzz
Jazz
Fizz
58
59
FizzJazzBuzz
61
62
Fizz
Jazz
Buzz
Fizz
67
Jazz
Fizz
Buzz
71
FizzJazz
73
74
FizzBuzz
Jazz
77
Fizz
79
JazzBuzz
Fizz
82
83
FizzJazz
Buzz
86
Fizz
Jazz
89
FizzBuzz
91
Jazz
Fizz
94
Buzz
FizzJazz
97
98
Fizz
JazzBuzz
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Your second bullet point is a bit vague... What's makes a division efficient? Why is that important for the challenge? \$\endgroup\$
    – Sanchises
    Mar 4, 2015 at 21:39
  • \$\begingroup\$ @sanchises, there still exist platforms, especially microcontrollers, that have very expensive (in cycles/time) division operations. At least one of the answers below avoids division/modulus altogether - but maybe hurts readability. It's something for voters to consider. \$\endgroup\$
    – gnibbler
    Mar 4, 2015 at 22:07
  • 1
    \$\begingroup\$ @sanchises not vague at all IMHO the point is not using division/modulus at all. You can do it just keeping a variable for each n=(3,4,5...) and reseting it at the time it ill match and print a word and incrementing when not. The Dry part can be doing a function/method receiving (n,word) and thus the "maintenance" of adding more words a breeze \$\endgroup\$
    – jean
    Mar 6, 2015 at 14:19
  • 1
    \$\begingroup\$ Highly relevant: themonadreader.files.wordpress.com/2014/04/fizzbuzz.pdf \$\endgroup\$
    – Hjulle
    Apr 10, 2015 at 11:35
  • 2
    \$\begingroup\$ You might enjoy this. \$\endgroup\$ May 1, 2015 at 21:37

54 Answers 54

1
2
1
\$\begingroup\$

Scala

Scala is a hybrid object-functional language on the JVM.

Solution

object FizzBuzzApp extends App {
    def fizz(i: Int) = if (i % 3 == 0) Some("Fizz") else None
    def jazz(i: Int) = if (i % 4 == 0) Some("Jazz") else None
    def buzz(i: Int) = if (i % 5 == 0) Some("Buzz") else None
    def combineFunctions(funs: ((Int) => Option[String])*)(i: Int) = {
        val result = funs.foldLeft("")((str, fun) => str + fun(i).getOrElse(""))
        if (result.isEmpty) i.toString else result
    }
    (1 to 100) map (combineFunctions(fizz, jazz, buzz)) foreach (println)
}

I hope that this is mostly comprehensible without an explanation. It could be more reusable if I used Scalaz to generalize combineFunctions to accept monoids, and folded the functions into an Option, but I'm at work at the moment.

\$\endgroup\$
1
\$\begingroup\$

C#

Maintainability: Just add one line per element
I iterate over each element in the dictionary, to check if it's a divisor of the current number, and adding to the string if it is.
Once finished, print the string, unless it is still null ( using the null coalescing operator ), in which case print the number plus an empty string to make it a string. ( I could use toString, but I guess that's a personal choice )

Dictionary<int, string> dict = new Dictionary<int, string>()
{
    {3, "Fizz"},
    {4, "Jazz"},
    {5, "Buzz"}
};
for (int i = 0; i < 100; i++)
{
    string msg = null;
    foreach (var pair in dict)
        if (i % pair.Key == 0)
            msg += pair.Value;
    Console.WriteLine(msg ?? i + "");
}
\$\endgroup\$
1
\$\begingroup\$

Python

Focus on readability and easy extensibility.

from itertools import izip

def fizzBuzz():
    for components in izip(xrange(1, 101), 
                           everyNth(3, 'Fizz'), 
                           everyNth(4, 'Jazz'), 
                           everyNth(5, 'Buzz')):
        print ''.join(components[1:]) if any(components[1:]) else components[0]

def everyNth(n, returnVal):
    while True:
        for _ in xrange(n-1):
            yield ''
        yield returnVal
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Since you like itertools - everyNth is better written as cycle(chain(repeat('', n-1), [returnVal])) \$\endgroup\$
    – gnibbler
    Mar 7, 2015 at 11:48
1
\$\begingroup\$

Whitespace

Sadly, StackOverflow seems to ignore spaces (Those whitespace haters!). Anyway, I've replaced all spaces with S, all tabs with T and all linefeeds with L:

SSST
L
LSSST
LSSSS
LSSST
LTTSS
LSSSSTT
LTSTT
LTSSTS
L
LS
LSTT
L
LSSSTS
LSSSS
LSSSS
LTTSSSSS
LSSSTTTTSTS
LSSSTTTTSTS
LSSSTTSTSST
LSSSTSSSTTS
L
LSTSTSS
L
LSSSTT
LS
LSSSSTSS
LTSTT
LTSSTST
L
LS
LSTTS
L
LSSSTST
LSSSS
LSSSS
LTTSSSSS
LSSSTTTTSTS
LSSSTTTTSTS
LSSSTTSSSST
LSSSTSSTSTS
L
LSTSTSS
L
LSSSTTS
LS
LSSSSTST
LTSTT
LTSSTTT
L
LS
LSTSSS
L
LSSSTTT
LSSSS
LSSSS
LTTSSSSS
LSSSTTTTSTS
LSSSTTTTSTS
LSSSTTTSTST
LSSSTSSSSTS
L
LSTSTSS
L
LSSSTSSS
LSSSS
LTTT
LTSSTSST
LS
LST
LST
LSSSTSST
LSSST
LTSSSS
LSSSSTTSSTSS
LTSSTSSSTSTS
LT
LSS
LTSSTSTS
L
LS
LST
L
LSSSTSS
LS
LS
LTSSTSTT
LT
LSS
LS
LSTSS
L
LSSSTSTT
LS
L
L
LT
L
LSSSTSTS
L
L
L
L
L

I used the following code as a regex:

push 1
label loop:
push 0
push 1
store
dup
push 3
mod
jump0 fizz
jump fizznext
label fizz:
push 0
push 0
store
pushrev "Fizz" + null
call puts
label fizznext:
dup
push 4
mod
jump0 jazz
jump jazznext
label jazz:
push 0
push 0
store
pushrev "Jazz" + null
call puts
label jazznext:
dup
push 5
mod
jump0 buzz
jump buzznext
label buzz:
push 0
push 0
store
pushrev "Buzz" + null
call puts
label buzznext:
push 0
retrieve
jump0 nonenext
dup
out number
label nonenext:
push 1
add
dup
push 100
sub
push '\n'
out char
jump0 end
jump loop
label puts:
dup
jump0 return
out char
jump puts
label return:
pop
ret
label end:
stop

(Yes 3 modulus, shut up) Fun fact: The code has 0 vissible characters! And last but not least (and most surprisingly): It works!

\$\endgroup\$
1
\$\begingroup\$

JavaScript

a={3:'Fizz',4:'Jazz',5:'Buzz'}
for(i=1; i<100; ++i)
{
  o=''
  for(z in a) 
    if(i%z==0) 
      o+=a[z]
  console.log(o||i)
}

Here is is a good implementation of FizzJazzBuzz, trying to follow the (fuzzy) specs given. It's not good for the original FizzBuzz problem (unlike the 'obvious answer')

The FizzBuzz specific says

  • prints the numbers from 1 to 100 but
  • for multiples of three print “Fizz” instead of the number
  • for the multiples of five print “Buzz”
  • for numbers which are multiples of both three and five print “FizzBuzz” - another word literally specified. It does not say "compose a 3rd word with the first and the second)

If in the future "FizzBuzz" changes to "Spritz" most of the program here have to be heavily revised...

\$\endgroup\$
1
\$\begingroup\$

Haskell/Skip-Halt-Print

Disclaimer: Shamelessly stolen (with permission) from: FizzBuzz in Haskell by Embedding a Domain-Specific Language by Maciej Piróg

The article shows the full derivation of the solution, which includes implementing FizzBuzz in an embedded domain specific language named "Skip-Halt-Print", and then simplify the code until that language disappears again.

Skip-Halt-Print

The language consists of the three operations, which can be shallow-embedded as:

type Program = String -> String
skip  = id       :: Program           -- Do nothing
halt  = const "" :: Program           -- Immediately halt the program
print = (++)     :: String -> Program -- Print the supplied string

Using this (and continuation-passing style) the FizzBuzz program can be written like this:

type Cont = Program → Program

fizz, buzz, base :: Int → Cont
fizz n | n `mod` 3 ≡ 0 = λx → print "fizz" ◦ x ◦ halt
       | otherwise     = id
buzz n | n `mod` 5 ≡ 0 = λx → print "buzz" ◦ x ◦ halt
       | otherwise     = id
base n                 = λx → x ◦ print (show n)

fizzbuzz :: Int → String
fizzbuzz n = (base n ◦ fizz n ◦ buzz n) skip ""

Solution

After inlining and simplifying we get the following solution:

fizzjazzbuzz :: Int → String
fizzjazzbuzz n = (test 3 "Fizz" . test 4 "Jazz" . test 5 "Buzz") id (show n)
  where
    -- test :: Int -> String -> Cont
    test d s x | n `mod` d == 0 = const (s ++ x "")
               | otherwise      = x

main :: IO ()
main = putStrLn . unlines $ map fizzjazzbuzz [1..99]

or if you want to, you can write it as

fizzes :: [(Int,String)]
fizzes = [(3,"Fizz"),(4,"Jazz"),(5,"Buzz")]

fizzjazzbuzz :: Int → String
fizzjazzbuzz n = foldr test id fizzes (show n)
  where
    -- test :: (Int, String) -> Cont
    test (d,s) x | n `mod` d == 0 = const (s ++ x "")
                 | otherwise      = x

main :: IO ()
main = putStrLn . unlines $ map fizzjazzbuzz [1..99]

Notes

One thing that is special about this solution is that it doesn't do the redundant test str == ""?str:show n, which most other solutions here does (see the article for details). This is possible because the continuation-passing gives more control over the program flow and allows the test function to choose if the number should be printed (by using halt).

\$\endgroup\$
1
\$\begingroup\$

AppleScript

Always loved the English nature of AppleScript. I'm taking advantage of the fact that "Fizz, Jazz, Buzz" are sequential. Here's what I got:

set fjb_strings to {"Fizz", "Jazz", "Buzz"}
repeat with x from 1 to 99
    set final_string to ""
    repeat with i from 1 to length of fjb_strings
        if (x mod (i + 2)) is 0 then
            set final_string to final_string & item i of fjb_strings
        end if
    end repeat
    if final_string is equal to "" then
        set final_string to x
    end if
    log final_string
end repeat

Output:

(*1*)
(*2*)
(*Fizz*)
(*Jazz*)
(*Buzz*)
(*Fizz*)
(*7*)
(*Jazz*)
(*Fizz*)
(*Buzz*)
(*11*)
(*FizzJazz*)
(*13*)
(*14*)
(*FizzBuzz*)
(*Jazz*)
(*17*)
(*Fizz*)
(*19*)
(*JazzBuzz*)
(*Fizz*)
(*22*)
(*23*)
(*FizzJazz*)
(*Buzz*)
(*26*)
(*Fizz*)
(*Jazz*)
(*29*)
(*FizzBuzz*)
(*31*)
(*Jazz*)
(*Fizz*)
(*34*)
(*Buzz*)
(*FizzJazz*)
(*37*)
(*38*)
(*Fizz*)
(*JazzBuzz*)
(*41*)
(*Fizz*)
(*43*)
(*Jazz*)
(*FizzBuzz*)
(*46*)
(*47*)
(*FizzJazz*)
(*49*)
(*Buzz*)
(*Fizz*)
(*Jazz*)
(*53*)
(*Fizz*)
(*Buzz*)
(*Jazz*)
(*Fizz*)
(*58*)
(*59*)
(*FizzJazzBuzz*)
(*61*)
(*62*)
(*Fizz*)
(*Jazz*)
(*Buzz*)
(*Fizz*)
(*67*)
(*Jazz*)
(*Fizz*)
(*Buzz*)
(*71*)
(*FizzJazz*)
(*73*)
(*74*)
(*FizzBuzz*)
(*Jazz*)
(*77*)
(*Fizz*)
(*79*)
(*JazzBuzz*)
(*Fizz*)
(*82*)
(*83*)
(*FizzJazz*)
(*Buzz*)
(*86*)
(*Fizz*)
(*Jazz*)
(*89*)
(*FizzBuzz*)
(*91*)
(*Jazz*)
(*Fizz*)
(*94*)
(*Buzz*)
(*FizzJazz*)
(*97*)
(*98*)
(*Fizz*)
\$\endgroup\$
1
  • \$\begingroup\$ Make it possible for programmers to write in English and you will find it is not possible for programmers to write in english. - Rule 00000111 of Computer Programming \$\endgroup\$
    – cat
    Mar 12, 2016 at 23:35
1
\$\begingroup\$

Python

My aim is not to write beautiful code as such, but instead code beautiful to Code Review.

Fizzy.py: import argparse import json

def Fizzy(ends, config, lambdas=[]):
    line = []
    for number in range(ends[0], ends[1] + 1) if len(ends) == 2 else ends:
        string = ''
        for key in config['words']:
            divisor, num, depth = int(key), number, 0
            while num % divisor == 0 and depth < config['max_repeats']:
                string += config['words'][key]
                num //= divisor
                depth += 1
        string = string if string else str(number)
        for lam in lambdas:
            string = lam(string, number)
            # TODO: include numbers ending in? e.g. 3 also matches 103, 1003, 83
        line.append(string)
    yield line


def FizzyReturn(ends, config, lambdas=[]):
    return '\n'.join(*Fizzy(ends, config, lambdas))


def FizzyPrint(ends, config, lambdas=[]):
    print(FizzyReturn(ends, config, lambdas))

if __name__ == '__main__':
    # TODO: iterator?
    parser = argparse.ArgumentParser(
        description='Return a section of the FizzBuzz sequence.')
    parser.add_argument(
        '--number', '--num', '-n', type=int, nargs=1, required=False,
        help='Number of the desired term.')
    parser.add_argument(
        '--ends', '-e', type=int, nargs=2, required=False,
        help='Start and end of the section.')
    parser.add_argument(
        '--config_path', '-c', type=str, default='Fizzy.json',
        help='Path of config JSON file. (default: Fizzy.json)')
    args = parser.parse_args()
    f = open(args.config_path)
    config = f.read()
    f.close()
    FizzyPrint(args.ends if args.ends else args.number, json.loads(config, object_pairs_hook=OrderedDict))

Fizzy.json:

{
    "max_repeats": 1,
    "words": {
        "3": "Fizz",
        "5": "Buzz"
    }
}

FizzyUnitTest.py:

import unittest
from collections import OrderedDict
from Fizzy import FizzyReturn as Fizzy

config = {
    'max_repeats': 1,
    'words': OrderedDict([('3', 'Fizz'), ('5', 'Buzz')])
}

config_repeats = {
    'max_repeats': 4,
    'words': OrderedDict([('3', 'Fizz')])
}


class TestFizzy(unittest.TestCase):
    def test_all(self):
        self.assertEqual(Fizzy([1, 15], config), '''1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz''')
        self.assertEqual(Fizzy([729], config_repeats), 'FizzFizzFizzFizz')
        self.assertEqual(
            Fizzy(
                [1, 15],
                config,
                [lambda s, n: 'A ' + s if n <= 10 else s]), '''A 1
A 2
A Fizz
A 4
A Buzz
A Fizz
A 7
A 8
A Fizz
A Buzz
11
Fizz
13
14
FizzBuzz''')

if __name__ == '__main__':
    unittest.main()
\$\endgroup\$
1
\$\begingroup\$

beeswax, 137 bytes

After solving the DRY problem for the 1,2,Fizz,4,Buzz challenge, this one was rather easy. Every mod operation is executed only once, check if n has to be printed or not (if Fizz or Jazz or both got printed before) is realized by using the global stack (gstack) as flag. If the stack is not empty, then the flag is set. Instruction f (after printing Fizz and/or Jazz) pushes the topmost local stack value onto the global stack, so if %5>0, the number only gets printed if gstack length (instruction A) is 0.

p?@<
p?{@b'gA<      p      <       p      <
q@`zzuB`d'%~5F@<f`zzaJ`b'%~4F@<f`zziF`b'%~3F<1_
 >??                        N@9P~0+.~@~-";~Pd

Adding more rules would let the source code grow only in a linear fashion.

\$\endgroup\$
0
\$\begingroup\$

Haskell

-- Just an import
import Control.Applicative

-- Some fixity declarations
infix 9 %
infix 8 ?
infix 9 %?
infix 9 +?+

-- just some helper definitions
n%i = n`mod`i

0?s = s
n?s = []

i%?s = \n -> n%i?s

-- The workhorse
fjb = (((++).).(++)) <$> (3%?"Fizz") <*> (4%?"Jazz") <*> (5%?"Buzz")

-- Casework
x+?+y = if null x then y else x

-- Main routine
main = do
    mapM_ (putStrLn.((+?+) <$> fjb <*> show)) [1..99]
\$\endgroup\$
1
  • 4
    \$\begingroup\$ Why are you specifying the fixity of your operators, and then use parenthesis around them anyways? (3%?"Fizz") \$\endgroup\$
    – Hjulle
    Mar 5, 2015 at 14:39
0
\$\begingroup\$

LiveScript

[1 til 100].for-each ->
  ([[3 \Fizz] [4 \Jazz] [5 \Buzz]].reduce do
    (prev, [n, word]) -> prev + switch it % n | 0 => word
                                              | _ => ""
    "")
    console.log switch .. | "" => it
                          | _  => ..

The only annoying duplication is in the reduce-arguments prev, n, and word, but I needed them to keep the destructuring neat.

I avoided referring to the results of the reduce by using LiveScript's cascade syntax (indent, then refer to preceding expression's return as ..).

If you enjoy golf:

[1 to 99].map ->[[3 \Fizz] [4 \Jazz] [5 \Buzz]].reduce ((p,[n,w])->p+if it%n then"" else w),""
  console.log ..||it

It's a lot like Doorknob's Ruby.

\$\endgroup\$
0
\$\begingroup\$

PHP

I know this isn't the most beautiful piece of code you saw this week.

But I tried to show something nice.

Here it is:

$if=function($cond, $true, $false){
    return $cond ? $true : $false;
};
$echo='printf';

for($i=1;$i<=100;$i++)
{
    "{$echo(
        $if(
            $i%5 && $i%4 && $i%3,
            $i,
            $if(!($i%3),'Fizz','').
            $if(!($i%4),'Buzz','').
            $if(!($i%5),'Jazz','')
        ).PHP_EOL
    )}";
}

This simply gives an anonymous function to a variable and a string to another one.
Inside that for loop, it has another string.

And that is where the magic happens.

You can try running it on http://writecodeonline.com/php/

\$\endgroup\$
0
\$\begingroup\$

Java 8

import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public enum Divisor {

    THREE(3, "Fizz"), FOUR(4, "Jazz"), FIVE(5, "Buzz");

    private final int divisor;
    private final String result;

    private Divisor(int divisor, final String result) {
        this.divisor = divisor;
        this.result = result;
    }

    public static String compute(int i) {
        final String temp = Stream.of(values())
                .filter(v -> i % v.divisor == 0)
                .map(v -> v.result)
                .collect(Collectors.joining());
        return temp.isEmpty() ? Integer.toString(i) : temp;
    }

    public static void main(String[] args) {
        process(parse(args.length > 0 ? args[0] : null, 1),
                parse(args.length > 1 ? args[1] : null, 100))
                .forEach(System.out::println);
    }

    private static int parse(final String value, int defaultValue) {
        try {
            final int result = Integer.parseInt(value);
            return result < 1 ? defaultValue : result;
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    private static Collection<String> process(int a, int b) {
        return IntStream.range(Math.min(a, b), Math.max(a, b)).mapToObj(Divisor::compute)
                .collect(Collectors.toList());
    }
}

Simply define additional divisors as a new Divisor enum value. The use of Java 8 eliminates explicit looping. The code defaults to looping between 1 and 99 inclusive, though one can over-ride that with command-line arguments.

\$\endgroup\$
0
\$\begingroup\$

Oracle SQL

To add another you just have to insert it into the mods table.

--Setup tables
create table mods (i number, s varchar2(4));
insert into mods values(3,'Fizz');
insert into mods values(4,'Jazz');
insert into mods values(5,'Buzz');
   
create table nums as (SELECT
    level i
      FROM DUAL
    CONNECT BY LEVEL < 100);
    
--Result
select 
nvl(
(
  select REPLACE(wm_concat(m.s), ',','') 
      from mods m where mod(n.i,m.i)=0
)
,n.i) from nums n;
\$\endgroup\$
0
\$\begingroup\$

Python 3

Because generators are funnier than loops

d = {3:'Fizz', 4:'Jazz', 5:'Buzz'}
print(*(''.join(d[i] for i in d if not n % i) or n for n in range(1,101)))
\$\endgroup\$
1
  • \$\begingroup\$ You should iterate over sorted(d) to make sure the words come in the correct order \$\endgroup\$
    – gnibbler
    Mar 8, 2015 at 20:07
0
\$\begingroup\$

Perl5

#!/usr/bin/perl

use strict;
use warnings;

my @period;
while(<DATA>){
    /^([0-9]+)\W(.*)$/;
    push @period, {c=>$1,n=>$1,t=>$2};
}
close DATA;

foreach my $r(1..100){
    my $string=join '', map {
        if(--$_->{c}){
            ''
        }else{
            $_->{c}=$_->{n};$_->{t}
        }
    } @period;
    print $string?"$string\n":"$r\n";
}
#period <tab> value
__DATA__
3   Fizz
5   Buzz
7   Woof
\$\endgroup\$
0
\$\begingroup\$

Python 2.7

start = 1
end = 100
output = range(0,end)
modified = [False] * end

for word, interval in [("Fizz", 3), ("Jazz", 4),("Buzz", 5)]:
    for i in range(0, end, interval):
        if modified[i]:
            output[i]+= word
        else:
            output[i] = word
            modified[i] = True

for entry in output[start:]:
    print entry
\$\endgroup\$
0
\$\begingroup\$

Swift

Here's FizzJazzBuzz in Swift, Apple's new programming language. Again, I'm taking advantage of the fact that FizzJazzBuzz is a sequential pattern:

let fjb_strings = ["Fizz", "Jazz", "Buzz"]
for i in 1...99
{
    var final_string = ""
    for j in 1...fjb_strings.count
    {
        final_string += (i % (j+2) == 0) ? fjb_strings[j-1] : ""
    }
    print(final_string == "" ? String(i) : final_string)
}

output:

1
2
Fizz
Jazz
Buzz
Fizz
7
Jazz
Fizz
Buzz
11
FizzJazz
13
14
FizzBuzz
Jazz
17
Fizz
19
JazzBuzz
Fizz
22
23
FizzJazz
Buzz
26
Fizz
Jazz
29
FizzBuzz
31
Jazz
Fizz
34
Buzz
FizzJazz
37
38
Fizz
JazzBuzz
41
Fizz
43
Jazz
FizzBuzz
46
47
FizzJazz
49
Buzz
Fizz
Jazz
53
Fizz
Buzz
Jazz
Fizz
58
59
FizzJazzBuzz
61
62
Fizz
Jazz
Buzz
Fizz
67
Jazz
Fizz
Buzz
71
FizzJazz
73
74
FizzBuzz
Jazz
77
Fizz
79
JazzBuzz
Fizz
82
83
FizzJazz
Buzz
86
Fizz
Jazz
89
FizzBuzz
91
Jazz
Fizz
94
Buzz
FizzJazz
97
98
Fizz
\$\endgroup\$
0
\$\begingroup\$

Scala (#2)

The other scala answer is fine but I think it could use less repetition. The first goal is DRY after all.

def buzzer(v: Int, value: String) = (i: Int) =>
    if (i % v == 0) Some(value) else None
val fizz = buzzer(3, "Fizz")
val jazz = buzzer(4, "Jazz")
val buzz = buzzer(5, "Buzz")
def combine(buzzers: Int => Option[String]*) = (i: Int) =>
    buzzers.flatMap(_(i)) match {
        case Nil => i.toString
        case result => result.mkString
    }

val fizzJazzBuzz = combine(fizz, jazz, buzz)
println((1 to 100) map fizzJazzBuzz)
\$\endgroup\$
0
\$\begingroup\$

A Ruby function, in functional programming style. Returns a string, that can be puts later. It's DRY; the only place to change for more "zz"s is the text hash.

def fizz_jazz_buzz
   text = {
      3 => "Fizz",
      4 => "Jazz",
      5 => "Buzz"
   }
   divide = ->(num, divisor) { num % divisor == 0 }
   (1..100).reduce("") do |acum, num|
      divisible_by = text.keys.map { |k| [k, divide.call(num, k)] }.to_h
      acum += text.select { |k, v| divisible_by[k] }.values.join
      acum += num.to_s if divisible_by.values.none? { |k| k }
      acum + "\n"
   end
end

Test code below. Should print "Pass" on passing, or "Fail" followed by the not-matching lines on failing.

def test
   expected = <<TEXT
1
2
Fizz
Jazz
Buzz
Fizz
7
Jazz
Fizz
Buzz
11
FizzJazz
13
14
FizzBuzz
Jazz
17
Fizz
19
JazzBuzz
Fizz
22
23
FizzJazz
Buzz
26
Fizz
Jazz
29
FizzBuzz
31
Jazz
Fizz
34
Buzz
FizzJazz
37
38
Fizz
JazzBuzz
41
Fizz
43
Jazz
FizzBuzz
46
47
FizzJazz
49
Buzz
Fizz
Jazz
53
Fizz
Buzz
Jazz
Fizz
58
59
FizzJazzBuzz
61
62
Fizz
Jazz
Buzz
Fizz
67
Jazz
Fizz
Buzz
71
FizzJazz
73
74
FizzBuzz
Jazz
77
Fizz
79
JazzBuzz
Fizz
82
83
FizzJazz
Buzz
86
Fizz
Jazz
89
FizzBuzz
91
Jazz
Fizz
94
Buzz
FizzJazz
97
98
Fizz
JazzBuzz
TEXT
   result = fizz_jazz_buzz
   puts (result == expected) ? "Pass" : "Fail"
   a = expected.split("\n")
   b = result.split("\n")
   (0...([a.size, b.size].max)).each { |i| 
      puts "#{a[i]}   #{b[i]}" if a[i] != b[i] 
   }
end

test
\$\endgroup\$
0
\$\begingroup\$

Javascript

Here's a bitflag version of sorts:

function checkFive(cnum) { if ( cnum / 5 == Math.floor( cnum / 5 ) ) { return "1"; } else { return "0"; }}
function checkFour(cnum) { if ( cnum / 4 == Math.floor( cnum / 4 ) ) { return "1"; } else { return "0"; }}
function checkThree(cnum) { if ( cnum / 3 == Math.floor( cnum / 3 ) ) { return "1"; } else { return "0"; }}
function getVals(cnum) { a = ["", "", ""]; a[0] = checkThree(cnum); a[1] = checkFour(cnum); a[2] = checkFive(cnum); return [a[0], a[1], a[2]]; }
function checkAll(cnum) {
  s = ["", "Fizz", "Jazz", "Buzz"];
  b = getVals(cnum);
  c = ["", "", ""];
  if(b[0] == "0") { c[0] = s[0];} else { c[0] = s[1];}
  if(b[1] == "0") { c[1] = s[0];} else { c[1] = s[2];}
  if(b[2] == "0") { c[2] = s[0];} else { c[2] = s[3];}
  if(b[0] == "0" && b[1] == "0" && b[2] == "0") { return cnum+""; } else { return c[0] + c[1] + c[2]; }
}
var count = 0;
while (count < 100) { document.body.innerHTML = document.body.innerHTML + "<div>" + checkAll(count+1); + "</div>"; count = 1 + count; }

Here's the Fiddle

\$\endgroup\$
0
\$\begingroup\$

DUP

For the explanation of the readable version, please scroll down ;)

I’m very sorry that I didn’t take the DRY aspect seriously enough, so here is a much better version that avoids duplication of code where not necessary:

    [/%$]⇒M['z,]⇒Z[ZZ]⇒ζ[[]]⇒β[Mβ]⇒‘[$$$3‘['F,'i,ζ]?\4‘['J,'a,ζ]?@5‘['B,'u,ζ]?**[$.]β?10,]c:0[$100<][1+c;!]#

To realize the DRY principle I made use of the operator definition functionality to simplify the program as far as possible:

Assignment of the MOD DUP combination for the three mod checks to operator M.

[/%$]⇒M


[/%$]⇒M
[$$$3M[]['F,'i,'z,'z,]?\4M[]['J,'a,'z,'z,]?@5M[]['B,'u,'z,'z,]?**[$.][]?10,]c:0[$100<][1+c;!]#

Assignment of the print single z character instruction set 'z, to operator Z.

['z,]⇒Z

[/%$]⇒M['z,]⇒Z
[$$$3M[]['F,'i,ZZ]?\4M[]['J,'a,ZZ]?@5M[]['B,'u,ZZ]?**[$.][]?10,]c:0[$100<][1+c;!]#

For even more efficient reuse of code, I assigned the duplication of Z to the operator ζ.

[ZZ]⇒ζ

[/%$]⇒M['z,]⇒Z[ZZ]⇒ζ
[$$$3M[]['F,'i,ζ]?\4M[]['J,'a,ζ]?@5M[]['B,'u,ζ]?**[$.][]?10,]c:0[$100<][1+c;!]#

And to to drive it to the max, I also assigned empty bracket pairs [] (that are used in the if-then-else constructs and while loops) to the operator β, because... why not?

[[]]⇒β

[/%$]⇒M['z,]⇒Z[ZZ]⇒ζ[[]]⇒β
[$$$3Mβ['F,'i,ζ]?\4Mβ['J,'a,ζ]?@5Mβ['B,'u,ζ]?**[$.]β?10,]c:0[$100<][1+c;!]#

It is obvious that three repetitions of are intolerable, so I assign this to the operator.

[Mβ]⇒‘

[/%$]⇒M['z,]⇒Z[ZZ]⇒ζ[[]]⇒β[Mβ]⇒‘
[$$$3‘['F,'i,ζ]?\4‘['J,'a,ζ]?@5‘['B,'u,ζ]?**[$.]β?10,]c:0[$100<][1+c;!]#

Wonderful! Compare this glorious contraption to the stale and boring old, way too inefficient and repetitive version:

[$$$3/%$[]['F,'i,'z,'z,]?\4/%$[]['J,'a,'z,'z,]?@5/%$[]['B,'u,'z,'z,]?**[$.][]?10,]c:0[$100<][1+c;!]#

In a more structured form:

[                                {function c start}
    $$$                          {duplicate value 3 times}
    3/%$[]['F,'i,'z,'z,]?        {value%3, if value%3=0 print Fizz}
    \4/%$[]['J,'a,'z,'z,]?       {swap, value%4, if value%4=0 print Jazz}
    @5/%$[]['B,'u,'z,'z,]?       {rotate, value%5, if value%5=0 print Buzz}
    **[$.][]?                    {multiply top 3 values, if result !=0 print number.}
    10,                          {print newline}
]c:                              {define function c}

0                                {start value}
[$100<][1+c;!]#                  {while value < 100, increment, call function c}

Example loop:

Assume we are are at n=6 (leads to better understandable stack values):

instr.        data stack
[
              6
$             6,6                   DUP
100           6,6,100
<             6,-1                  7<100 ? → -1 (truthy value)
]
[
1             6,1
+             7
c;!                                 push c, fetch value of c (its start value), execute c
$$$           7,7,7,7               DUP 3 times
3             7,7,7,7,3
/             7,7,7,1,2             (produces mod, div)
%             7,7,7,1               POP
$             7,7,7,1,1             DUP
[]['F,'i...]? 7,7,7,1               POP, popped value !=0, nothing is done
\             7,7,1,7               SWAP
4             7,7,1,7,4
/             7,7,1,3,1             MOD/DIV
%             7,7,1,3
$             7,7,1,3,3
[]['J,'a...]? 7,7,1,3               POP, popped value !=0, nothing is done
@             7,1,3,7               ROT
5             7,1,3,7,5
/             7,1,3,2,1
%             7,1,3,2
$             7,1,3,2,2
[]['B,'u...]? 7,1,3,2
*             7,1,6                 MUL twice. If %3,%4 or %5 were zero, the result
*             7,6                   is zero. (if Fizz, Jazz or Buzz were printed)
[                                   0 is the falsy value. So if something was printed before, the first bracket of [$.][]?                                
$             7,7                   is not entered, the number not printed.
.             7                     STDOUT: 7
][]?
10            7,10
,             7                     STDOUT: Char(10)=newline
[$100         7,7,100               continue while loop
<]            7,-1
...

Try out the code in this online DUP interpreter or clone my Julia implementation of DUP on GitHub. My GitHub page comes with a detailed explanation of DUP.

\$\endgroup\$
0
\$\begingroup\$

bc, 2686 bytes

/*************************************************************************
*       _____ _            _               ____                          *
*      |  ___(_)________  | | __ _ _______| __ ) _   _ ________          *
*      | |_  | |_  /_  /  | |/ _` |_  /_  /  _ \| | | |_  /_  /          *
*      |  _| | |/ / / / |_| | (_| |/ / / /| |_) | |_| |/ / / /           *
*      |_|   |_/___/___\___/ \__,_/___/___|____/ \__,_/___/___|          *
*                                                                        *
*                                                                        *
*    FizzJazzBuzz function, using "professional" coding standards        *
*                                                                        *
*************************************************************************/

/* define a `bc` function that takes no input */
/* input arguments may be added in future     */

define fjb()
{
        /* set up parameters: important for futureproofing */
        target_max_iterations=100
        integer_one=1
        integer_two=1
        integer_zero=0
        integer_three=3
        integer_four=4
        integer_five=5
        true=integer_two
        false=2

        /* i: iterate from one to one hundred  */
        for(i=1;i<=target_max_iterations;i++)
        {
                /* fjb_word: flags when a word was triggered      */
                /*          initialise to false                   */
                fjb_word=false

                /* Fizz condition: test for divisibility by three */
                if(i%3==integer_zero)
                {
                        fjb_word=true
                        print "Fizz"
                }

                /* Jazz condition: test for multiple of four      */
                if(i%4==integer_zero)
                {
                        fjb_word=1
                        print "Jazz"
                }

                /* Buzz condition: test for modulus of five       */
                if(i%5==integer_zero)
                {
                        fjb_word=integer_two
                        print "Buzz"
                }

                /* Else condition: fall through to here if none   */
                /* of Fizz, Jazz, or Buzz were triggered          */
                if(fjb_word==false)
                {
                        /* print current value */
                        print i
                }

                /* But we always need to print a carriage return  */
                print "\n"
        }
        /* the function has completed, so exit */
        print "\n"
        print "fjb() exit status : "
        return integer_zero
}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Thinking about it, I probably need to go back and define more functions, fi(i), ja(i), bu(i), to abstract out some "complexity" and be more DRY \$\endgroup\$
    – roblogic
    Feb 10 at 11:37
-2
\$\begingroup\$

JavaScript

DRY && OO

In the lack of DRY solutions not using modulus/division I wrote it. Also it's an exercise in OO (yes, I know there's no real OO with JS)

You can see it running at JSFiddle

//FizzJazzBuzz 
var zzClass = function(){

    this.divisor;
    this.word;
    this.count;
};

zzClass.prototype = {
    isZZ : function(){
        if (this.count == this.divisor)
        {
            this.count = 1;
            return this.word;
        }
        else
        {
           this.count++;
           return '';
        }
    }
}

function initZZ(w,d)
{    
    var x = Object.create(zzClass.prototype
       , { divisor :{ value : d }, word: { value : w } }
     );

     x.count = 1;

     return x;
}

// Declare array of ZZ's
var arrZZ = [
    initZZ('Fizz',3),
    initZZ('Jazz',4),
    initZZ('Buzz',5)    
    ]

var phrase = '';

for (var i = 1; i < 101; i++)
{
    phrase = '';

    for (var j=0; j<arrZZ.length; j++)
    {
        phrase = phrase + arrZZ[j].isZZ();
    }

    if (phrase == '') phrase = i;

    console.log(phrase);
}   

We presume using a simple conditional and a variable to count when to print is "cheaper" than using modulus or division. An efficient way to calculate a minimum common multiple

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.