
FizzBuzz, A Deep Navel to Gaze Into - ashleyblackmore
http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html
======
kstenerud
Actually, the control flow only requires you to know that you've done
SOMETHING out of the ordinary, but not WHAT you've done. A C example that is
easily extensible:

    
    
        void fizzBuzz(void)
        {
            bool alternateUsed = false;
            for(int i = 1; i <= 100; i++)
            {
                if(i % 3 == 0)
                {
                    printf("Fizz");
                    alternateUsed = true;
                }
                if(i % 5 == 0)
                {
                    printf("Buzz");
                    alternateUsed = true;
                }
    
                if(!alternateUsed)
                {
                    printf("%d", i);
                }
                printf("\n");
                alternateUsed = false;
            }
        }
    

All you need to know for the decision to print the bare number is whether an
alternate (Fizz or Buzz) was used in this iteration. Furthermore, FizzBuzz is
described such that you stack alternates (FizzBuzz for values that are
multiples of 3 and 5). In this example, they stack automatically, with the
order of "if" statements determining the priority. Want to change it to print
"BuzzBazzFizz" for multiples of 5, 4, and 3? No problem!

    
    
            if(i % 5 == 0)
            {
                printf("Buzz");
                alternateUsed = true;
            }
            if(i % 4 == 0)
            {
                printf("Bazz");
                alternateUsed = true;
            }
            if(i % 3 == 0)
            {
                printf("Fizz");
                alternateUsed = true;
            }
    

Yes, imperative languages can be a bit cumbersome at times, but elegant
solutions are still possible.

------
tetha
I don't entirely like his generalized fizz buzz (with the printers and such),
because it doesn't capture the way I read the requirements well.

The requirements to me read as: I have pairs of number-sets and strings, and
whenever a number is divisible by all numbers in the set, the application is
supposed to output the associated string. If multiple sets of numbers fulfill
this property, the string associated with the largest set is used. If no group
matches, output the number. Note that this specification contains a loophole:
What if one set is [1, 2] and the other set is [2, 4] and the number is 4?
This is undefined.

From such a data structure, deriving the generalized program is rather simple
and straightforward and from there, I don't entirely see the reason to go nuts
with functional programming and category theory and whatsoever, because the
generalized solution is a rather simple folding operation and the biggest
complications come from the hole in the spec.

------
ollysb
This seems a far more obvious way to code the extensible case:

    
    
        def fizzbuzz(max)
          (1..max).each do |n|
            labels = []
    
            labels << "fizz" if n % 3 == 0
            labels << "buzz" if n % 5 == 0
            labels << "bazz" if n % 7 == 0
    
            puts labels.empty? ? n : labels.join
          end
        end
    
        fizzbuzz(105)

