1. 12
  1. 6

    [1, 2, “Fizz”, 4, “Buzz”, “Fizz”, 7, 8, “Fizz”, “Buzz”, 11, “Fizz”, 13, 14, “FizzBuzz”, 16, 17, “Fizz”, 19, “Buzz”, “Fizz”, 22, 23, “Fizz”, “Buzz”, 26, “Fizz”, 28, 29, “FizzBuzz”, 31, 32, “Fizz”, 34, “Buzz”, “Fizz”, 37, 38, “Fizz”, “Buzz”, 41, “Fizz”, 43, 44, “FizzBuzz”, 46, 47, “Fizz”, 49, “Buzz”, “Fizz”, 52, 53, “Fizz”, “Buzz”, 56, “Fizz”, 58, 59, “FizzBuzz”, 61, 62, “Fizz”, 64, “Buzz”, “Fizz”, 67, 68, “Fizz”, “Buzz”, 71, “Fizz”, 73, 74, “FizzBuzz”, 76, 77, “Fizz”, 79, “Buzz”, “Fizz”, 82, 83, “Fizz”, “Buzz”, 86, “Fizz”, 88, 89, “FizzBuzz”, 91, 92, “Fizz”, 94, “Buzz”, “Fizz”, 97, 98, “Fizz”, “Buzz”]

    Copied and pasted, and probably not the best way to answer in an interview.

    1. 5

      I’ve got tons of them, two of my favorites are “Euclid’s solution”

      def fizz_buzz(n: int) -> str:
          hi, lo = max(n, 15), min(n, 15)
      
          while hi % lo > 0:
              hi, lo = lo, hi % lo
      
          return {1: str(n), 3: "fizz", 5: "buzz", 15: "fizzbuzz"}[lo]
      

      and the trigonometric solution:

      def fizz_buzz(n: int) -> str:
          fizz = 'fizz' * int(math.cos(n * math.tau / 3))
          buzz = 'buzz' * int(math.cos(n * math.tau / 5))
          return (fizz + buzz) or str(n)
      

      (Self-promotion corner: I wrote a book on the topic.)

      1. 5

        ‘If’ is a red herring. Write one without branching at the assembly level. If you think any jne/jnz is fine, if is fine as well.

        1. 3

          A more mathematical solution to a Fizzbuzz without if’s (though dictionary lookup is arguable). Previous discussion

          1. 2

            That solution just pushes the if’s into the cond form:

            { 1: n, 6: "Fizz", 10: "Buzz", 0: "FizzBuzz" }
            

            There’s another if in this form:

            for n in range(100)
            
          2. 2

            A few years ago I decided to see how thoroughly I could overengineer fizzbuzz in JavaScript. The fact I decided to use the sum of two waves means that it doesn’t need any conditionals or modulo. Behold:

            // How many ms between fizzbuzz calls?
            const RATE = 100;
            
            // FizzBuzz Parameters
            const FIZZ_PERIOD = 3;
            const BUZZ_PERIOD = 5;
            
            // Map waves to final output values in range [ 0..3 ]
            const FIZZ_AMPLITUDE = 1;
            const BUZZ_AMPLITUDE = 2;
            
            // Lookup table for results
            const LOOKUP = [ undefined, "Fizz", "Buzz", "FizzBuzz" ];
            
            // Generate a square wave
            const squareWave = period => amplitude => n =>
              amplitude * Math.max( 0, Math.floor( Math.cos( n * 2 * Math.PI / period ) + 0.5 ) );
            
            // Compose the fizzbuzz function out of waves components
            const fizzbuzz = n => LOOKUP[ [
              squareWave( FIZZ_PERIOD )( FIZZ_AMPLITUDE ),
              squareWave( BUZZ_PERIOD )( BUZZ_AMPLITUDE ),
            ].reduce( ( prev, curr ) => curr( n ) + prev, 0 ) ] || n;
            
            // Async sleep to avoid busyloop
            const sleep = async ms => new Promise( resolve => setTimeout( resolve, ms ) );
            
            // Generate an infinite sequence starting from some base
            function* seq( start = 1 ) {
              for ( let i = start; true; ++i ) {
                yield i;
              }
            }
            
            // FizzBuzz Forever!
            async function main() {
              for ( const i of seq() ) {
                console.log( i, fizzbuzz( i ) );
                await sleep( RATE );
              }
            }
            
            // Start
            main();
            
            1. 3

              Isn’t Math.max a conditional?

              1. 4

                I suppose that was cheating slightly, but “no conditionals” wasn’t my original intent. The sum-of-waves method was just intended to be needlessly obtuse. It happens to have this property as a side-effect.

                There are other ways to generate a square wave that don’t have hidden conditionals. This one is nicer and fixes a bug I just noticed in the original (when used with different periods than 3 & 5):

                // Generate a square wave
                const squareWave2 = period => amplitude => n =>
                  amplitude * ( Math.cos( n * Math.PI / period ) & 1 );
                

                Also, thinking about it, the || could also be considered a hidden conditional, but it can be eliminated by just not hard-coding the lookup table and making n be the first entry every time.

                1. 4

                  With squareWave2 this program gives the wrong answer for i = 64084278. With squareWave it gives the wrong answer for i = 895962678003541 (and maybe lower values of i as well, I did not check).

                  1. 3

                    Turns out the 2nd one is good up for all inputs up to 2^25. After that it would need another wave function that doesn’t rely on floating point. This one should be correct until integer overflow:

                    const squareWave3 = period => amplitude => n =>
                      amplitude * !( n % period );
                    

                    Sadly this re-introduces the rather cliché modulo operator, but I don’t think that can be avoided if the promise of “FizzBuzz Forever!” is to be upheld. At least, this one should be good for all values of forever < 2^54. To go any higher than that reliably, I’d need to go through the whole program and suffix all the numbers with n to use BigInt.

            2. 1

              Generate masks and update with masks. That is the standard way of vectorizing.

              1. 1

                Does this also count?:

                fizzbuzz = lambda n: [[str(n), 'Buzz'][n % 5 == 0], ['Fizz', 'Fizz Buzz'][n % 5 == 0]][n % 3 == 0]
                
                1. 1

                  No, I think that they would consider the dict lookup to be equivalent to a conditional. This is well supported, as historical advice for implementing a swtich-statement in Python has been to use a dict for dispatch by looking up functions for each case.

                  I think the Python equivalent to the posted code would be…

                  from itertools import cycle, count, islice
                  fizzbuzz = lambda ds={3: 'fizz', 5: 'buzz', 7: 'quux'}: zip(count(), zip(*(cycle([[term], *[[]] * (div - 1)]) for div, term in ds.items())))
                  print(*[*islice(fizzbuzz(), 20)], sep='\n')
                  

                  or the equivalent

                  from itertools import repeat, cycle, repeat, count, islice, chain
                  from functools import reduce
                  from operator import add
                  fizzbuzz = lambda ds={3: 'fizz', 5: 'buzz', 7: 'quux'}: islice(zip(count(), (reduce(add, ts) for ts in zip(*(cycle(chain([[term]], repeat([], div - 1))) for div, term in ds.items())))), 1, None)
                  print(*[*islice((str(n) if not ts else ''.join(ts) for n, ts in fizzbuzz()), 20)], sep='\n')
                  

                  (I’m a little surprised that the posted Haskell version strictly returns strings, rather than some compound type with the original numeric value separate from the matched terms. There’s not much you can do with this output, other than print it to the screen…)

                  1. 2

                    I did not use any dictionaries, it’s a list. I’ll be honest, I also didn’t read the OP; I just thought it would be a neat tiny challenge to come up with something if-less in a Python one-liner :P

                    1. 1

                      Funny, because this was my Python solution. There is a conditional, yes, but no pattern matching… it’s quite minimal.

                      f = "fizz"
                      b = "buzz"
                      fb = f+b
                      block = [None, None, f, None, b, f, None, None, f, b, None, f, None, None, fb]
                      from itertools import cycle
                      list(map(lambda x, y: x or str(y), cycle(block), range(1, 101)))
                      
                    1. 1
                      #include <stdio.h>
                      const int N = 100;
                      #define F(m, x) for (int i = m; i <= N; i += m) x
                      int main(void) {
                        char fb[N + 1][10];
                        F(1, sprintf(fb[i], "%d", i));
                        F(3, sprintf(fb[i], "Fizz"));
                        F(5, sprintf(fb[i], "Buzz"));
                        F(15, sprintf(fb[i], "FizzBuzz"));
                        F(1, printf("%s\n", fb[i]));
                      }
                      
                      1. 1

                        I did one of these in Python for a collection of amusing solutions to phone-screen problems.

                        Others in that repo include Fibonacci generator with no integer literals and no arithmetic operators, and an is_square() that’s only one line (and that I finally got around to updating today because of this post; I’ve had people pose it with “0 is a square” and with “0 is not a square”, and decided the published version should correctly assert 0 is a square).

                        Here it is in all its glory:

                        from itertools import accumulate, count, takewhile
                        
                        is_square = lambda n: n == 0 or n > 0 and n in takewhile(lambda x: x <= n, accumulate(filter(lambda n: n & 1, count())))
                        
                        1. 1

                          You mean fizzbuzz while hiding the if clause in a function call??

                          1. 1

                            Next generation fizzbuzz: Write a fizzbuzz program without executing any conditionals in your mind while you are writing it.