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.
(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 19There’s no reason to be clever, otherwise, you end up with something like: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition ;-)
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:
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)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))))))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:
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
my answer in c++
#includeusing 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";
}