Fizzbuzz

March 23, 2021

Let’s begin with the basic problem of enumerating the numbers from 1 to N (excluding N) in the most basic way possible:

(define (fb1 n) ; straight forward method
  (define (fb n)
    (cond ((zero? (modulo n 15)) 'FizzBuzz)
          ((zero? (modulo n 5)) 'Buzz)
          ((zero? (modulo n 3)) 'Fizz)
          (else n)))
  (map fb (range 1 n)))

A second method uses a little bit of number theory to characterize the divisibility of a number without using a string of conditional statements; I’ll leave to you the pleasure of figuring out why it works:

(define (fb2 n) ; number theory method
  (define (fb n)
    (cdr (assoc (modulo (* n n n n) 15)
      `((1 . ,n) (6 . Fizz) (10 . Buzz) (0 . FizzBuzz)))))
  (map fb (range 1 n)))

A third method, which will be the fastest for large N, uses sieving:

(define (fb3 n) ; sieving method
  (let ((xs (list->vector (range n))))
    (do ((i 3 (+ i 3))) ((<= n i))
      (vector-set! xs i 'Fizz))
    (do ((i 5 (+ i 5))) ((<= n i))
      (vector-set! xs i 'Buzz))
    (do ((i 15 (+ i 15))) ((<= n i))
      (vector-set! xs i 'FizzBuzz))
    (cdr (vector->list xs))))

We turn now to the Project Euler version of FizzBuzz. Here is a simple method that tests divisibility of each number from 1 to N:

(define (fb4 n) ; simple euler method
  (let loop ((i 1) (s 0))
    (cond ((= n i) s)
          ((or (zero? (modulo i 3))
               (zero? (modulo i 5)))
            (loop (+ i 1) (+ s i)))
          (else (loop (+ i 1) s)))))

And here is a method that runs in O(1) time using a formula developed by Gauss to calculate the sum of the first N integers:

(define (fb5 n) ; gauss summation method
  (define (g n) (* n (+ n 1) 1/2))
  (+ (* 3 (g (quotient (- n 1) 3)))
     (* 5 (g (quotient (- n 1) 5)))
     (* -15 (g (quotient (- n 1) 15)))))

You can run the program at https://ideone.com/rI6hCX.

Advertisement

Pages: 1 2

8 Responses to “Fizzbuzz”

  1. Pascal Bourguignon said
    (defun fizz-buzz-sum (N)
      (loop for i from 1 below N
            when (or (zerop (mod i 3)) (zerop (mod i 5)))
              sum i))
    
    (mapcar 'fizz-buzz-sum '(10 1000))
    ; --> (23 233168)
    
    (defun fizz-buzz (N)
      (loop for i from 1 below N
            if (zerop (mod i 3))
              if (zerop (mod i 5))
                do (write-line "FizzBuzz")
              else
                do (write-line "Fizz")
              end
            else
              if (zerop (mod i 5))
                do (write-line "Buzz")
              else
                do (format t "~D~%" i)
              end
            end))
    
    (fizz-buzz 20)
    
    1
    2
    Fizz
    4
    Buzz
    Fizz
    7
    8
    Fizz
    Buzz
    11
    Fizz
    13
    14
    FizzBuzz
    16
    17
    Fizz
    19
    
    
  2. Pascal Bourguignon said

    There’s no reason to be clever, otherwise, you end up with something like: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition ;-)

  3. Daniel said

    Here’s a solution in Python.

    N = 25
    
    for i in range(1, N + 1):
        s = ''
        if i % 3 == 0:
            s += 'Fizz'
        if i % 5 == 0:
            s += 'Buzz'
        if not s:
            s = str(i)
        print(s)
    
    print('----------')
    
    print(sum(x for x in range(1, 1000) if x % 3 == 0 or x % 5 == 0))
    

    Output:

    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
    ----------
    233168
    
  4. Daniel said

    “you can use a simple method, but it is more fun to be a little bit clever”

    Here’s my attempt at a clever solution.

    for i in range(1, 26):
        s = 'Fizz' if not i % 3 else ''
        s += 'Buzz' if not i % 5 else ''
        print(s if s else i)
    
  5. Kevin said

    A solution in Racket:

    (define (fizzbuzz)
      (define dct #hash((0 . FizzBuzz) (6 . Fizz) (10 . Buzz)))
      (for ((n (in-range 1 101)))
        (let ((elr (modulo (expt n 4) 15)))
          (displayln (if (= 1 elr) n (dict-ref dct elr))))))
    
  6. Kevin said

    Another solution in Racket:
    (The first post was for 1 – 100, as requested by Project Euler; this post is for 1 to N.)

    (define (fizzbuzz N)
      (let ((dct #hash((0 . FizzBuzz) (6 . Fizz) (10 . Buzz))) (n-max (add1 N)))
        (for ((n (in-range 1 n-max)))
          (let ((elr (modulo (expt n 4) 15)))
            (displayln (if (= 1 elr) n (dict-ref dct elr)))))))
    

    Example:

    > (fizzbuzz 15)
    1
    2
    Fizz
    4
    Buzz
    Fizz
    7
    8
    Fizz
    Buzz
    11
    Fizz
    13
    14
    FizzBuzz
    
  7. Ernest Gore said

    For the Sum from 1 to N in C#:

    (3(N/3)(N/3 + 1) + 5(N/5)(N/5 + 1) – 15(N/15)(N/15 + 1))/2

  8. faisi said

    my answer in c++

    #include
    using namespace std;
    int main()
    {
    int setc = 0;
    int N = 100;
    for (int i = 1; i < N; i++)
    {
    setc = 0;
    if (i % 3 == 0)
    {
    setc = 1;
    cout << "Fizz";
    }
    if (i % 5 == 0)
    cout << "Buzz";

        else if(setc==0)
            cout << i;
        cout << endl;
    
    
    }
    return 0;
    

    }

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 )

Connecting to %s

%d bloggers like this: