Can anyone else comment on this? Most canonical FizzBuzz programs special case 15, and I don't get it.
Can anyone else comment on this? Most canonical FizzBuzz programs special case 15, and I don't get it.
for i in range(1i, 101) {
match (i % 3, i % 5) {
(0, 0) => println!("Fizzbuzz"),
(0, _) => println!("Fizz"),
(_, 0) => println!("Buzz"),
_ => println!("{}", i),
}
}Well, sure, explicitly calling out i % 15 rather than (i % 3) && (i % 5) or the equivalent has that problem.
> In my opinion, pattern matching offers the most direct solution and comes with an abundance of compiler optimizations.
Pattern matching is not available in many languages, but, sure, where its available, its a great choice. Note that this still has a distinct case for the case where both % 3 and % 5 are true, rather than just testing those cases independently and sequentially and concatenating, so I think it falls into the general class of solutions I was describing.
fizzBuzz n
| n `mod` 15 == 0 = "FizzBuzz"
| n `mod` 3 == 0 = "Fizz"
| n `mod` 5 == 0 = "Buzz"
| otherwise = show n
main = mapM_ (print . fizzBuzz) [1..100]
I agree with you about generalizing pattern matching for less simple cases. Your example brought to mind view patterns, about which Oliver O'Charles had a nice writeup recently [1]. Nifty little extension.[1] https://ocharles.org.uk/blog/posts/2014-12-02-view-patterns....
let buzzer number =
match number with
| i when i % 3 = 0 && i % 5 = 0 -> "FizzBuzz"
| i when i % 3 = 0 -> "Fizz"
| i when i % 5 = 0 -> "Buzz"
| i -> (sprintf "%i" i)
for i = 1 to 100 do
printfn "%s" (buzzer i)Some of us know that clients ALWAYS change their minds, specs are rarely equivalent to the end result, and code against future changes that are trivial to account for in advance.
Additionally, using %15 is not DRY. If the spec changes from saying "Fizz" on multiples of 3 to saying "Fizz" on multiples of 4, then you will have to also update 15->20. If you forget to do this, you have a bug.
The correct implementation is dependent on the problem's context, and such context is not available with the FizzBuzz problem.
It's kind of a trivial test for that sort of recognition, but anything as small as FizzBuzz is going to be rather trivial.
Really, the FizzBuzz test is a check to see if someone is bullshitting when they say they can code. Testing deeper than that is expecting too much of it.
Of course, it can be actually shorter with a goto.
1\n2\nFizz\n4\nBuzz\n...\nFizzBuzz\n
If you did not print anything for some cases, you're right that it could not be unconditional (though it could still be done at the end with a flag).
string output = numb.toString();
if(numb % 3 == 0) ouput = "Fizz";
if(numb % 5 == 0) output.Append("Buzz");
write output;
It is possible to use two checks to cover all three fizzbuzz components.for i in range(1,100):print("Fizz"(i%3==0) + "Buzz"(i%5==0) or i)
For the record, I have utterly no math background (hardly passed algebra), but I also agree that checking only 3 and 5 is the better solution and is how I've always written FizzBuzz.
if x isDivisibleBy 3: print "Fizz"
if x isDivisibleBy 5: print "Buzz"
and.. how do I now print x in the neither case? I can't 'else'. I could make a long if not divisible by either if expression, but that's less easy to read than an if/else chain that starts out with 'if divisible by both, print fizzbuzz'.If fizzbuzz was: Print FizzBuzz for multiples of 15, fizz for multiples of 3, and buzz for multiples of 5, and nothing otherwise, I bet you'd see the above pseudocode far more.