FizzBuzz: una sfida per programmatori

Un quesito che viene spesso richiesto ai programmatori è quello di scrivere un programma FizzBuzz:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

La difficoltà principale, se così vogliamo chiamarla, è quella di leggere attentamente i requisiti e trasformarli in if condizionali del linguaggio scelto. Nel mio caso, Java:

import junit.framework.Assert;

public class FizzBuzz {
    public static void main(String args[]) {
        for (int i = 1; i <= 100; i++) {
            if (i % 3 == 0 && i % 5 == 0) {
                System.out.println("fizzbuzz");
                Assert.assertTrue(divisibleBy3(i) && divisibleBy5(i));
            } else if (i % 3 == 0) {
                System.out.println("fizz");
                Assert.assertTrue(divisibleBy3(i) && !divisibleBy5(i));
            } else if (i % 5 == 0) {
                System.out.println("buzz");
                Assert.assertTrue(!divisibleBy3(i) && divisibleBy5(i));
            } else {
                System.out.println(i);
                Assert.assertTrue(!divisibleBy3(i) && !divisibleBy5(i));
            }

        }
    }

L’algoritmo si può complicare a piacere. In una curiosa implementazione, viene richiesto di non usare operazioni come la moltiplicazione e la divisione. L’autore del post risolve il problema utilizzando una coda circolare, sfruttando il fatto che i numeri seguono un comportamento periodico.
Nel risolvere lo stesso problema, ho deciso di utilizzare un approccio diverso. Infatti, mi sono ricordato che esistono dei criteri per stabilire a priori se un numero è divisibile per determinati numeri (in particolare per 3 e per 5). E così ho scritto due metodi per testare se un numero passato come parametro è divisibile per 3 o per 5:

    public static boolean divisibleBy3(int num) {
        String s = new Integer(num).toString();
        while (s.length() != 1) {
            int j = 0;
            for (int i = 0; i < s.length(); i++) {
                j += Integer.parseInt(s.substring(i, i + 1));
            }
            s = new Integer(j).toString();
        }
        if (s.equals("3") || s.equals("6") || s.equals("9"))
            return true;
        return false;
    }

    public static boolean divisibleBy5(int num) {
        String s = new Integer(num).toString();
        String lastDigit = s.substring(s.length() - 1, s.length());
        if (lastDigit.equals("5") || lastDigit.equals("0"))
            return true;
        return false;
    }
}

E applicarlo al FizzBuzz è un’operazione elementare.

2 thoughts on “FizzBuzz: una sfida per programmatori”

Leave a Reply