12 ms·
Why do most implementations of FizzBuzz special case % 15? I haven't ever really understood this. Maybe it's just my math-y background, but it always seemed to
by vessenes 12y ago
Why do most implementations of FizzBuzz special case % 15? I haven't ever really understood this. Maybe it's just my math-y background, but it always seemed to me you should just check mod 3 and mod 5 without an else between them, concatenating Fizz and Buzz.
Can anyone else comment on this? Most canonical FizzBuzz programs special case 15, and I don't get it.
- rudolf0 12y agoEasier to understand for beginners, I suppose. 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.
- donmcc 12y agoIt's to neatly handle the line break.
- vessenes 12y agoI suppose it's a style issue as to whether an extra mod is better than checking if one of the triggers has passed. I would propose it's more DRY to do it the short way though.
- pcmonk 12y agoIt's not any shorter. The extra check as to whether or not to print the line break cancels out the mod 15 check. In my opinion, it's cleaner to have three conditionals of the same type than two checking mods and a third checking the OR of the first two. Of course, it can be actually shorter with a goto.
- boomlinde 12y agoWhether you print the number, Fizz, Buzz or FizzBuzz you are going output a line break, so I'm not sure what you would be checking for. Output \n unconditionally.
- deleted 12y ago[deleted]
- zem 12y agothen you'd get \n \n fizz\n \n buzz\n rather than fizz\n buzz\n
- blt 12y agoThen you call `printf` twice every loop instead of once. `printf` is buffered so you aren't making two system calls, but you are still making two function calls.
- boomlinde 12y agoMaybe it's a performance/brevity compromise, but the latter is the issue the I addressed. The least-calls solution would probably be to print the whole output as a single string constant.
- stonemetal 12y agostring 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.
- im2w1l 12y ago5Buzz
- mden 12y agoIn some languages you can hide the extra check: for i in range(1,100):print("Fizz"(i%3==0) + "Buzz"(i%5==0) or i)
- thedufer 12y agoFor others who are confused by this syntax, it appears that there are *'s that got eaten and turned into italics.
- wenderen 12y agoI do that too. It seems more in the spirit of the problem. For an alternate problem, in which you are asked to print strings a, b and c (!= a concat b) if the number is divisible by 3, 5 and 15 respectively, it makes sense to special case 15.
- deleted 12y ago[deleted]
- PhearTheCeal 12y agonoice, here's my version print("\n".join([("FIZZ"*(i%3==0)+"BUZZ"*(i%5==0)) or str(i) for i in range(1,101)]))
- kaonashi 12y agoI would hope never to find a bomb like that in the code I'm maintaining.
- SwellJoe 12y agoReally? I find that one line far more pleasant than the Python example above it, with variables being assigned, etc. Both are quite clear in their intention, I think, assuming you recognize "join". I don't even recognize the language of the one-liner, but it makes perfect sense to me as a reader. It looks like a Perlish solution, but the string method is strange, I think. Maybe Perl 6 or Ruby?
- cgh 12y agoIt's Python as well.
- nostrademons 12y agoThe one-liner is valid Python. It's slightly non-idiomatic in that it uses a list-comprehension where a generator expression would do, and uses range instead of xrange (in Python 2.x; in 3.x range is the idiomatic alternative).
- nightpool 12y agoit's also non-idomatic in that is uses string-multiplication and ==0 where an "if not" ternary expression would be much cleaner.
- masukomi 12y agojust because 15 HAPPENS to be a concatenation of the output of 3 and the output of 5 today doesn't mean it will be tomorrow. If I said "say Fizz for multiples of 3, Buzz for multiples of 5, and 'this is a silly coding problem' for multiples of 3 and 5 then you'd have to rewrite your code. 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.
- Doji 12y agoFor any implementation you can manufacture an example which will require a person to re-structure their code. 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.
- tracker1 12y agoIf you're using something like JS, where strings are truthy, you can always do something like this... https://gist.github.com/tracker1/d58fa1f83ab17d37eb2c https://gist.github.com/tracker1/d58fa1f83ab17d37eb2c
- masukomi 12y agoPart of my point (which i obviosuly didn't communicate well) is that Fizz concatenated with Buzz is a premature optimization. It's the developer taking advantage of a linguistic coincience. The instructions are to output 3 different strings based on %3, %5, or %3 and %5. I have never seen a set of fizzbuzz instructions that actually specified that the last option should be a concatenation of the 1st two. It's always specified as a 3rd string that people independently notice is a concatenation of the two.
- Legion 12y agoThis is absolutely true for real-world coding. However, for the purposes of an exercise, I think the fact that 15 was chosen was not an accident, but is part of the exercise. Does the coder recognize the relationship between the multiples, and recognize the ability to optimize by removing an extraneous comparison? It's kind of a trivial test for that sort of recognition, but anything as small as FizzBuzz is going to be rather trivial.
- dragonwriter 12y agoWell, its more direct in that, while it increases the number of branches, it minimizes the number of statements executed on any branch. It's also the solution that maps most directly to the problem statement, and, absent a strong technical reason to do otherwise, a direct mapping from requirements to code is a good thing.
- icedog 12y agoI disagree that it maps most directly to the problem statement. You're performing a common factor computation in your mind, which may be more difficult given numbers other than 3 and 5. In my opinion, pattern matching offers the most direct solution and comes with an abundance of compiler optimizations. Here's an example in Rust... for i in range(1i, 101) { match (i % 3, i % 5) { (0, 0) => println!("Fizzbuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }
- dragonwriter 12y ago> I disagree that it maps most directly to the problem statement. You're performing a common factor computation in your mind, which may be more difficult given numbers other than 3 and 5. 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.
- icedog 12y agoI'll take an extra branch over concatenation and dealing with new line chars any day.
- 12y ago
- FnuGk 12y agoAnother thing i dont understand is why people hardcode 15. I would rather write (3 * 5) and let the compiler figure out that 3 * 5=15. This way i think it more clearly states where the number 15 comes from. Any reason to write 15 over (3 * 5)?
- lfender6445 12y agointeresting point, but I feel the same could be said for (3 * 5)
- rzwitserloot 12y agoBecause of the requirement to print the number if it is divisible by neither. Here: 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.