DEV Community

loading...
Cover image for [Challenge] 🐝 FizzBuzz without if/else

[Challenge] 🐝 FizzBuzz without if/else

nombrekeff profile image Keff Updated on ・1 min read

This challenge is intended for Javascript, but you can complete it with any language you like and can.


Most of us will know the FizzBuzz game/exercise and probably have done it many times. It should be a simple and straightforward exercise for most developers...

BUT can you do it without using if/else statements?


Challenge Description

Write a program that outputs the string representation of numbers from 1 to N.

But for multiples of 3, it should output "Fizz" instead of the number and for the multiples of 5 output "Buzz". For numbers which are multiples of both 3 and 5, you should output "FizzBuzz".

Curveball: You must not use if/else statements, and ideally, no ternary operator.

Example:

const n = 15;

/* 
Return:
  [
    "1",
    "2",
    "Fizz",
    "4",
    "Buzz",
    "Fizz",
    "7",
    "8",
    "Fizz",
    "Buzz",
    "11",
    "Fizz",
    "13",
    "14",
    "FizzBuzz"
  ]
*/
Enter fullscreen mode Exit fullscreen mode

I will comment my solution in a couple of days.

💪 Best of luck! 💪


Credits:
Cover Image from https://codenewbiesite.wordpress.com/2017/01/29/fizz-buzz/

Discussion (95)

pic
Editor guide
Collapse
stephanie profile image
Stephanie Handsteiner • Edited

Easy, just do it in CSS.

ol {
    list-style-type: inside;
}

li:nth-child(3n), li:nth-child(5n) {
    list-style-type: none;
}

li:nth-child(3n):before {
    content: 'Fizz';
}

li:nth-child(5n):after {
    content: 'Buzz';
}
Enter fullscreen mode Exit fullscreen mode

Needs some Markup to display obviously.

Collapse
ben profile image
Collapse
lifelongthinker profile image
Sebastian

This is truly ingenious!

Collapse
nombrekeff profile image
Keff Author

Magnificent! I knew there were going to be really neat solutions!!

Thanks for sharing your solution 💪

Collapse
bpedroza profile image
Bryan

Javascript taking advantage of || operator:

function fizzBuzz(n) {
  let output = [1];
  const map = {
    3: 'Fizz',
    5: 'Buzz',
    15: 'FizzBuzz'
  };
  for(let i = 2; i <= n; i++) {
    // Multiply by -1 to move false positives for buzz and fizzBuzz out of range 
    const fizz = i % 3 * -1 + 3;
    const buzz = i % 5 + 5;
    const fizzBuzz = fizz * buzz;
    const value = map[fizzBuzz] || map[fizz] || map[buzz] || i;
    output.push(value);
  }

  return output;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
lifelongthinker profile image
Sebastian

This is what makes my developer heart jump for joy 😍😁 Awesome, Bryan!

Collapse
bpedroza profile image
Bryan

That made my day. Thanks. 😀

Collapse
nombrekeff profile image
Keff Author

Cool solution! I thought to do something similar at first, but ended up doing some weird stuff!

Collapse
rushsteve1 profile image
Steven vanZyl

The cleanest and best FizzBuzz implementation I know of doesn't use any if statements at all. Actually it doesn't use any control flow at all in most languages.
The approach is fully described here: philcrissman.net/posts/eulers-fizz...

On my Repl.it I also have this same approach implemented in several other languages:
repl.it/@rushsteve1/

Collapse
coreyja profile image
Corey Alexander

This was great! Love it when there is a simple probable mathematic solution to these kinds of things!

Collapse
nombrekeff profile image
Keff Author

Me too, so clean! I love maths but I'm crap at it myself xD

Collapse
nombrekeff profile image
Keff Author

I did not know about this, thanks for sharing. I will remember this!

Collapse
lifelongthinker profile image
Sebastian
function print(max)
{
  for(var n = 1; n <= max; n++)
  {
    ifThenElse(
      n%3 == 0, 
      function() { 
        ifThenElse(
          n%5 == 0,
          function() { console.log("FizzBuzz"); },
          function() { console.log("Fizz"); }
        );
      },
      function() {
        ifThenElse(
          n%5 == 0,
          function() { console.log("Buzz"); },
          function() { console.log(n); }
        );
      }
    );
  }
}

function ifThenElse(i,t,e) {
  while(i)
  {
    t.call();
    return;
  }

  e.call();
}

print(15);
Collapse
nombrekeff profile image
Keff Author

Neat solution, thanks for sharing it!

Is there a reason you use t.call() instead of calling the function directly t()?

Collapse
lifelongthinker profile image
Sebastian

Thanks. Yes, haha, the reason is that my head was a bit worn out so late at night 🤪. I have another improvement, will post it shortly.

Thread Thread
nombrekeff profile image
Keff Author

Ohh yup, I know that feeling xD

Thread Thread
lifelongthinker profile image
Sebastian

Here we go. This is a bit more streamlined:

const ifThenElse = (i,t,e) => {
    return () => {
        while(i) {
            t();
            return;
        }

        e();   
    }
};

const printFizzBuzz = (max) => {
  for(let n = 1; n <= max; n++) {
    ifThenElse(
        n%3 == 0, 
        ifThenElse(
            n%5 == 0, 
            () => console.log("FizzBuzz"), 
            () => console.log("Fizz")
        ),
        ifThenElse(
            n%5 == 0,
            () => console.log("Buzz"),
            () => console.log(n)
        )
    )();
  }
};

printFizzBuzz(15);
Collapse
agtoever profile image
agtoever • Edited

Holy sh*t, my other solution was really ugly! :-o
Here is a (much) better one (also in Python3):

def fizzbuzz(n):
    for i in range(1, n + 1):
        print([f'{i}', f'Fizz', f'Buzz', f'FizzBuzz'][(i % 3 == 0) + 2 * (i % 5 == 0)])

fizzbuzz(22)

This works using the property that True in Python has numerical value 1 and using f-strings in an array. The proper element in the array is chosen based on the mentioned property, checking for divisibility with 3 and 5.

Collapse
nastyox1 profile image
nastyox • Edited

logical operators

The second half of an "and" statement only evaluates if the first half is true.

for(var i = 1; i < 100; i++){
    !(i % 3) && document.write("fizz");
    !(i % 5) && document.write("buzz");
    i % 3 && i % 5 && document.write(i);
    document.write(" ");
}

...

for loops

For loops check your second declaration on each iteration. Force it to be false on the second iteration, and you've got something that'll check your condition a single time.

for(var i = 1; i < 100; i++){
    for(var j = 0; !j && !(i % 3); j++) document.write("fizz");
    for(var j = 0; !j && !(i % 5); j++) document.write("buzz");
    for(var j = 0; !j && i % 3 && i % 5; j++) document.write(i);
    document.write(" ");
}

...

arrays

Referencing an index that that exists gives you the value stored there, but referencing an index that doesn't exist gives you undefined. Use an "or" statement to give yourself a fallback value when this happens, and you'll be ready to go.

var fizz = ["fizz"], buzz = ["buzz"];
for(var i = 1; i < 100; i++) document.write((((fizz[i % 3] || "") + (buzz[i % 5] || "")) || i) + " ");

Or, fill an array with your options, and leverage the fact that true can be used as 1 in JavaScript to do some index-selection math.

var arr = [null, "fizz", "buzz", "fizzbuzz"];
for(var i = 1; i < 100; i++){
    arr[0] = i;
    document.write(arr[!(i % 3) + !(i % 5) * 2] + " ");
}

...

try/catch blocks

You can purposefully throw exceptions when a boolean is false by referencing a variable that doesn't exist (the "throwException" variable in this case).

function tryIf(test, pass, fail){
    try{
        !test || throwException;
        (fail || function(){})();
    }
    catch(e){
        pass();
    }
}

for(var i = 1; i < 100; i++){
    tryIf(!(i % 3), function(){
        document.write("fizz");
    });

    tryIf(!(i % 5), function(){
        document.write("buzz");
    });

    tryIf(i % 3 && i % 5, function(){
        document.write(i);
    });

    document.write(" ");
}

...

while loops

This is the same concept as for loops. Force the loop to stop after one iteration (this time with a break), and you've got something that'll check your condition a single time.

for(var i = 1; i < 100; i++){
    while(!(i % 3)){
        document.write("fizz");
        break;
    }

    while(!(i % 5)){
        document.write("buzz");
        break;
    }

    while(i % 3 && i % 5){
        document.write(i);
        break;
    }

    document.write(" ");
}

...

switch statements

Who could forget the classic alternative to if statements? Technically not even cheating!

for(var i = 1; i < 100; i++){
    switch(i % 3){
        case 0:
            document.write("fizz");
        default:
    }

    switch(i % 5){
        case 0:
            document.write("buzz");
        default:
    }

    switch(!(i % 3 && i % 5)){
        case false:
            document.write(i);
        default:
    }

    document.write(" ");
}
Collapse
nombrekeff profile image
Keff Author

Wow, those are some solutions right there! Thanks a lot for sharing and taking the time to explain it.

I did some silly stuff, just for fun lol:

function fizzBuzz(number = 100) {
    let current = 1;
    let string = '';

    while (current <= number) {
        string += current + ' ';
        current += 1;
    }

    string = string.trim()
        .replace(/[0-9]+/g, (match) => {
            const valueMap = ['FizzBuzz', match];
            const index = match % 15;
            return valueMap[index] || match;
        })
        .replace(/[0-9]+/g, (match) => {
            const valueMap = ['Fizz', match];
            const index = match % 3;
            return valueMap[index] || match;
        })
        .replace(/[0-9]+/g, (match) => {
            const valueMap = ['Buzz', match];
            const index = match % 5;
            return valueMap[index] || match;
        })

    return string.split(' ');
}
Collapse
vonheikemen profile image
Heiker • Edited

You can still have flow control with functions.

const troo = (iff, elz) => iff;
const falz = (iff, elz) => elz;
const choose = (value) => [falz, troo][Number(Boolean(value))];

const is_fizz = (n) => choose(n % 3 === 0);
const is_buzz = (n) => choose(n % 5 === 0);

const fizzbuzz = (n) =>
  is_fizz(n) (
    () => is_buzz (n) ("FizzBuzz", "Fizz"),
    () => is_buzz (n) ("Buzz", n),
  )
    .call();

const range = (end) =>
  new Array(end).fill(null).map((val, index) => index + 1);

range(15).map(fizzbuzz).join(", ");
Collapse
nombrekeff profile image
Keff Author

I liked this approach! Thanks for sharing!

Collapse
rad_val_ profile image
Valentin Radu

Here's the simplest I can think of without any statements. 🙃

function run(n, i=1, j=1, k=1, acc=[]) {
  !j && k && acc.push('fizz')
  !k && j && acc.push('buzz')
  !k && !j && acc.push('fizzbuzz')
  k && j && acc.push(i)

    n - 1 && run(n - 1, i + 1, (j + 1) % 3, (k + 1) % 5, acc)
  return acc
}

console.log(run(30))
Collapse
nombrekeff profile image
Keff Author

Nice, recursion for the win 💪

Collapse
nombrekeff profile image
Keff Author

Thanks for sharing!

Collapse
jdaless profile image
John D'Alessandro

I do feel like this was kinda cheap...

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    foreach(var s in FizzBuzz().Take(15))
      Console.WriteLine(s);
  }

  public static IEnumerable<string> FizzBuzz()
  {
    for(int i = 1; true; i++)
    {
      for(;i%3!=0 && i%5!=0;)
      {
        yield return i.ToString();
        break;
      }
      for(;i%3==0;)
      {
        for(;i%5==0;)
        {
          yield return "FizzBuzz";
          break;
        }
        yield return "Fizz";
        break;
      }
      for(;i%5==0;)
      {
        yield return "Buzz";
        break;
      }
    }
  }
}
Collapse
nocnica profile image
Nočnica Fee

I like it!

Collapse
nombrekeff profile image
Keff Author

Nice stuff! Cool use of a generator. And yeah kinda cheap but cool nonetheless, thanks for sharing!

Collapse
ehsan profile image
Ehsan Azizi • Edited

Here is an ugly solution in one line

for (let i = 1; i <= number; i++) {
  console.log((i % 3 === 0 && i % 5 === 0 && 'fizzbuzz') || (i % 3 === 0 && 'fizz') || (i % 5 === 0 && 'buzz') || i);
}
Collapse
imshravan profile image
Shravan Kumar B

U aren't supposed to use Ternary Operator.

Collapse
ehsan profile image
Ehsan Azizi • Edited

Oh yeah! didn't notice that, I have updated my solution

Collapse
martinsebastian profile image
Martin Sebastian • Edited
const fizzBuzz = (until) => {
      const fizz = ["Fizz", "", ""];
      const buzz = ["Buzz", "", "", "", ""];

      (function fizzybuzzy(current) {
         console.log(fizz[current % 3] + buzz[current % 5]  || current);

         return (current + 1 <= until) && fizzybuzzy(current + 1);
     })(0);
}

fizzBuzz(100);
Collapse
martinsebastian profile image
Martin Sebastian • Edited

Some improvement to my earlier version.

A) better (arguably, because way more cognitive load than the very simple one above)

const fizzBuzz = (until, current = 0, fizzbuzz = ["", "Fizz", "Buzz"]) => {
    const fizzybuzzy = () => fizzbuzz[!(current % 3) * 1] + fizzbuzz[!(current % 5) * 2]  || current;
    return (current + 1 <= until) && (console.log(fizzybuzzy()), fizzBuzz(until, current + 1));
}

fizzBuzz(100);

B) above one as 1 liner b/c hello perl

const devBuzz = (function i(u, c= 0, m=["", "dev", ".to"])  {(c+1<=u) && (console.log(m[!(c % 3)*1] + m[!(c%5)*2] || c), i(u,c+1));});

devBuzz(20);
Collapse
martinsebastian profile image
Martin Sebastian

Also thinking about overriding Number.prototype.toString makes a fun thingy. Maybe someone already did, but someone for sure should :D

Collapse
jpantunes profile image
JP Antunes

There was a similar and equally really good thread about a month ago that had some devilishly clever solutions... highly recommend it!

My contributions below:

//1
const fizzBuzz = n => {
    const mapper = (arr, modulo, txt) => arr
                                    .filter(e => e % modulo == 0)
                                    .forEach(e => arr[arr.indexOf(e)] = txt);
    let x = 1;
    const range = [...Array(n)].map(_ => x++)
    mapper(range, 15, 'FizzBuzz');
    mapper(range, 5, 'Buzz');
    mapper(range, 3, 'Fizz');
    return range.toString();
}

//2
const fizzBuzz = n => {
    let x = 1;
    const range = [...Array(n)].map(_ => x++);
    for (let i = 2; i <= n; i += 3) range[i] = 'Fizz';
    for (let i = 4; i <= n; i += 5) range[i] = 'Buzz';
    for (let i = 14; i <= n; i += 15) range[i] = 'FizzBuzz';
    return range.toString();
}

//3
const fizzBuzz = n => {
    const isFizzBuzz = n => ( {false: '', true: 'Fizz'}[n % 3 == 0] 
                            + {false: '', true: 'Buzz'}[n % 5 == 0] 
                            || n.toString() );
    let x = 1;
    return [...Array(n)].map(_ => isFizzBuzz(x++)).toString();                             
}

//4 ...originally from a Kevlin Henney presentation here: https://youtu.be/FyCYva9DhsI?t=1191
const fizzBuzz = n => {
  const test = (d, s, x) => n % d == 0 ? _ => s + x('') : x;
  const fizz = x => test(3, 'Fizz', x);
  const buzz = x => test(5, 'Buzz', x);
  return fizz(buzz(x => x))(n.toString());
}
Collapse
nombrekeff profile image
Keff Author

Nice stuff. I will be checking out the thread!

There have been some really clever solutions posted here as well.

Collapse
mintypt profile image
mintyPT

Here is some python for you :)

print([
  (not (i % 3) and not (i % 5) and "FizzBuzz") or
  (not (i % 3) and "Fizz") or
  (not (i % 5) and "Buzz") or
  i
  for i in range(1,16)])
Collapse
imshravan profile image
Shravan Kumar B • Edited
function fizzBuzz(n){
   let arr = [ ];
   for(i=1 ; i<=n; i++){
      let flag = i%15==0 && arr.push('FizzBuzz') || i%5==0 && arr.push('Buzz') || i%3==0 && arr.push('Fizz');
      !flag && arr.push(i);
   }

 return arr;
}



console.log(fizzBuzz(15));

Manolo Edge
@nombrekeff

Collapse
darthbob88 profile image
Raymond Price

First obvious solution is to use nested ternaries to get around the if/else restriction, but the rules also frown on ternaries.

Second option is switch/case on ii % 15, like

for (var ii = 1; ii <= 100; ii++) {
    switch (ii % 15) {
        case 0: console.log("Fizzbuzz"); break;
        case 1: console.log(ii); break;
        case 2: console.log(ii); break;
        case 3: console.log("Fizz"); break;
        case 4: console.log(ii); break;
        case 5: console.log("Buzz"); break;
        case 6: console.log("Fizz"); break;
        case 7: console.log(ii); break;
        case 8: console.log(ii); break;
        case 9: console.log("Fizz"); break;
        case 10: console.log("Buzz"); break;
        case 11: console.log(ii); break;
        case 12: console.log("Fizz"); break;
        case 13: console.log(ii); break;
        case 14: console.log(ii); break;
    }
}

I believe you can also do this with an array, console.log(options[ii%15]), but I don't care enough to test that would actually work for JS.

Another option I've seen and liked is seeding the RNG with the correct value and using the outputs from that to index an array of options to print, something like srand(MAGIC); for (var ii = 1; ii <= 100; ii++) print ["Fizz", "Buzz", "Fizzbuzz", ii][rand.next() % 4]; } But that definitely doesn't work in JS, since you can't seed the RNG.

Collapse
rawkode profile image
David McKay

There's a lack of pattern matching and recursion in the comments, so here we go:

defmodule FizzBuzz do
  def run(0) do
    IO.puts("Finished")
  end

  def run(n) when is_integer(n) do
    n
    |> fizzbuzz(rem(n, 3), rem(n, 5))
    |> run()
  end

  defp fizzbuzz(n, 0, 0) do
    IO.puts("#{n}: FizzBuzz")

    n - 1
  end

  defp fizzbuzz(n, 0, _) do
    IO.puts("#{n}: Fizz")
    n - 1
  end

  defp fizzbuzz(n, _, 0) do
    IO.puts("#{n}: Buzz")
    n - 1
  end

  defp fizzbuzz(n, _, _) do
    IO.puts("#{n}")
    n - 1
  end
end

Collapse
nombrekeff profile image
Keff Author

Nice, thanks for sharing this approach.

Rickard Laurin just posted another similar approach in ReasonML as well.

Collapse
kubadlo profile image
Jakub Leško

My solution in Rust:

fn main() {
    for n in 1..=15 {
        match n % 3 + n % 5 {
            0 => {
                println!("FizzBuzz");
                continue;
            }
            _ => {}
        }

        match n % 5 {
            0 => {
                println!("Buzz");
                continue;
            }
            _ => {}
        }

        match n % 3 {
            0 => {
                println!("Fizz");
                continue;
            }
            _ => {}
        }

        println!("{}", n);
    }
}
Collapse
benwtrent profile image
Benjamin Trent • Edited

Clojure example.

I quite like Andrew's bit shift array example. Only think that its better to have a nil zeroth value so you get circuit breaking for free.

;; Array for grabbing appropriate string, if exists
(def fizzes [nil "Fizz" "Buzz" "FizzBuzz"])

;; boolean to integer conversion
(defn b-to-i [b]
  (bit-and 1 (bit-shift-right (Boolean/hashCode b) 1)))

(defn fizzit [n]
  (let [fizzed (b-to-i (= 0 (mod n 3)))                     ;1 if true
        buzzed (bit-shift-left (b-to-i (= 0 (mod n 5))) 1)  ;2 if true
        both (+ fizzed buzzed)]                             ;3 if both are true
    (or (get fizzes both) (str n)))
  )

(defn fizzbuzz [n]
  (map fizzit (range 1 (inc n))))

repl.it link

Collapse
agtoever profile image
agtoever

A solution in Python. Feels silly though...

def fizzbuzz(n):
    offset = 0
    while n > 0:
        cycle = list(range(offset, 15 + offset))
        for i in range(3, 15, 3):
            cycle[i] = 'Fizz'
        for i in range(5, 15, 5):
            cycle[i] = 'Buzz'
        cycle.append('FizzBuzz')
        cycle.remove(offset)
        print('\n'.join(map(str, cycle[:min(15, n)])))
        offset += 15
        n -= 15


fizzbuzz(22)
Collapse
nombrekeff profile image
Keff Author

Wait until you see mine 😂

Collapse
paul_the_agile profile image
Paul the Agile

Here's my initial cut at a Python solution:

n = 15
a = ['{}', '{}', 'Fizz', '{}', 'Buzz', 'Fizz', '{}', '{}', 'Fizz', 'Buzz', '{}', 'Fizz', '{}', '{}', 'Fizz Buzz']
for i in range(n):
    print(a[i % 15].format(i+1))

This just cycles through the array and prints the appropriate response, though I've already seen more clever ways to do it.

Collapse
russsaidwords profile image
Russ Edwards

Here's a solution to the challenge in JavaScript...

function fizzBuzz (n) {
    let i = 1
    let fbline = []
    let output = []
    let count = 0
    while (i <= n) {
        fbline = [i, i, i, "Fizz", i, "Buzz", "Fizz", i, i, "Fizz", "Buzz", i, "Fizz", i, i, "FizzBuzz"]
        output.push("" + fbline[(i+count) % 16])
        i++
        count = Math.floor(i / 16)
    }
    console.log(output)
}
fizzBuzz(90)

Here's a repl.it where you can run this.

Collapse
imjoseangel profile image
Jose Angel Munoz

Here you have in Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import (division, absolute_import, print_function,
                        unicode_literals)


class FizzBuzz:
    def __init__(self):
        self.fizzbuzz = dict()

        for num in range(3, 101, 3):
            self.fizzbuzz[num] = "Fizz"

        for num in range(5, 101, 5):
            self.fizzbuzz[num] = "Buzz"

        for num in range(15, 101, 15):
            self.fizzbuzz[num] = "FizzBuzz"

        self.run()

    def run(self):

        for number in range(1, 101):
            print(self.fizzbuzz.get(number, number))


def main():

    FizzBuzz()


if __name__ == '__main__':
    main()
Collapse
scgrk profile image
Stephen Gerkin

Came up with 2 in Kotlin. Both could definitely be improved, but this was a fun exercise in thinking about control flow!

fun main() {
    for (i in 1..20) {
        println(fizzBuzz(i))
    }
    for (i in 1..20) {
        println(fizzBuzz2(i))
    }
}

// Technically no if or ternary!
fun fizzBuzz(num: Int) = when {
        num % 15 == 0 -> "FizzBuzz"
        num % 3  == 0-> "Fizz"
        num % 5  == 0-> "Buzz"
        else -> num.toString()
}

fun fizzBuzz2(num: Int): String {
    val isFizz = num % 3 == 0
    val isBuzz = num % 5 == 0

    while (isFizz && isBuzz) return "FizzBuzz"
    while (isBuzz) return "Buzz"
    while (isFizz) return "Fizz"

    return num.toString()
}
Collapse
anras573 profile image
Anders Bo Rasmussen • Edited

I did something similar to your fizzbuzz in C# 8.0:

public static void Main()
{       
    for (var i = 1; i < 31; i++)
    {
        Console.WriteLine(FizzBuzz(i));
    }
}

public static string FizzBuzz(int number)
{
    return number switch
    {
        _ when number % 15 == 0 => "FizzBuzz",
        _ when number % 3 == 0 => "Fizz",
        _ when number % 5 == 0 => "Buzz",
        _ => number.ToString()
    };
}
Collapse
martis347 profile image
Martynas Kan

Really nice idea!

Here's how I did it 😁

const fizzBuzz = (number) => {
    const array = Array(number).fill(undefined).map((_, index) => index + 1);
    const fiz = array.filter(v => !(v % 3))
    const baz = array.filter(v => !(v % 5))
    const fizBaz = array.filter(v => !(v % 5) && !(v % 3))

    let result = {};
    for (let i of array) {
        result[i] = i;
    }
    for (let f of fiz) {
        result[f] = 'Fizz';
    }
    for (let b of baz) {
        result[b] = 'Buzz';
    }
    for (let fb of fizBaz) {
        result[fb] = 'FizzBuzz';
    }

    return Object.values(result);
}
Collapse
nombrekeff profile image
Collapse
wdhowe profile image
wdhowe

One of the ways in Clojure:

(defn divisible?
  "Determine if a number is divisible by the divisor with no remainders."
  [div num]
  (zero? (mod num div)))

(defn fizz-buzz
  "Fizz if divisible by 3, Buzz if divisible by 5, FizzBuzz if div by both, n if neither."
  [n]
  (cond-> nil ; threaded value starts with nil (falsey)
    (divisible? 3 n) (str "Fizz") ; if true, adds Fizz to the threaded value (nil)
    (divisible? 5 n) (str "Buzz") ; if true, adds Buzz to the threaded value (nil or Fizz)
    :always-true     (or n))) ; return the threaded value if not nil (Fizz/Buzz) or n

(let [start 1
      stop 20]
  (println "FizzBuzz:" start "-" stop)
  (doseq [x (range start (+ 1 stop))] (println (fizz-buzz x))))

Original idea seen here: clojuredocs.org/clojure.core/cond-...

Collapse
thorstenhirsch profile image
Thorsten Hirsch

Here's a solution I like very much, because it uses function composition:

// helpers
const range = (m, n) => Array.from(Array(n - m + 1).keys()).map(n => n + m);
const compose = (fn1, ...fns) => fns.reduce((prevFn, nextFn) => value => prevFn(nextFn(value)), fn1);
const isDivisibleBy = divider => replacer => value => value % divider === 0 ? replacer : value;

// fizzbuzz definition
const fizz = isDivisibleBy(3)("Fizz");
const buzz = isDivisibleBy(5)("Buzz");
const fizzBuzz = isDivisibleBy(15)("FizzBuzz");

// this is what I like most about this implementation
const magic = compose(fizz, buzz, fizzBuzz);

console.log(range(1, 100).map(magic));

It's heavily inspired by tokdaniel's gist.

Collapse
codemouse92 profile image
Jason C. McDonald • Edited

Ironically, I have a Python-based solution for this as an example in my upcoming EuroPython 2020 presentation!

def fizz_buzz(max):
    return [
        "fizz" * (not n % 3) +
        "buzz" * (not n % 5)
        or str(n)
        for n in range(max + 1)
    ]

I picked up the * trick on a StackOverflow answer about this a while back, but I adapted it.

Collapse
believer profile image
Rickard Natt och Dag

Here's an example in ReasonML

Runnable example: sketch.sh/s/XABe2ghxBqncDWTTKpNK8n/

module FizzBuzz = {
  let make = value =>
    switch (value) {
    | (0, 0, _) => "FizzBuzz"
    | (0, _, _) => "Fizz"
    | (_, 0, _) => "Buzz"
    | (_, _, value) => string_of_int(value);
    }
};

for (index in 1 to 100) {
  print_endline(FizzBuzz.make((index mod 3, index mod 5, index)));
};
Collapse
dimitrimarion profile image
Dimitri Marion
const div3 = x => x % 3 == 0;
const div5 = x => x % 5 == 0;

const fizzBuzz = n => Array.from(Array(n+1).keys(), 
                                 x => div3(x) && div5(x) && "FizzBuzz" || div3(x) && "Fizz" || div5(x)  && "Buzz" || String(x))
                                 .slice(1);
Collapse
jselbie profile image
John Selbie • Edited

Trick is to map the modulo results into a true/false value. Then use that as a 0 or 1 index into an array of two strings.

C++

void fizzbuzz(int N)
{
    const string fizzstrings[2] = { "Fizz", "" };
    const string buzzstrings[2] = { "Buzz", "" };

    for (int i = 1; i <= N; i++)
    {
        int fizz = !!(i % 3);   // 0 if i is divisible by 3, 1 otherwise
        int buzz = !!(i % 5);   // 0 if i is divisible by 5, 1 otherwise
        int use_number = fizz && buzz;    // 1 if is neither divisible by 3 or 5, 0 otherwise
        string table[2] = { "", to_string(i) };
        cout << fizzstrings[fizz] << buzzstrings[buzz] << table[use_number] << endl;
    }
}

And the above can be further reduced to a single array table by exploiting multiplication against a bool expression

void fizzbuzz(int N)
{
    for (int i = 1; i <= N; i++)
    {
        const string fb[4] = { "", "Fizz", "Buzz", to_string(i) };
        int fizz = !(i % 3);                   // 0 or 1
        int buzz = (!(i % 5)) * 2;             // 0 or 2
        int numIndex = (!fizz && !buzz) * 3;   // 0 or 3
        cout << fb[fizz] << fb[buzz] << fb[numIndex] << endl;
    }
}