11 ms·
FizzBuzz in Too Much Detail
- a_bonobo 11y agoRuby has the added bonus of Flip Flops to make everything even more opaque! a=b=c=(1..100).each do |num| print num, ?\r, ("Fizz" unless (a = !a) .. (a = !a)), ("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))), ?\n end Add comments as needed Source: http://www.reddit.com/r/ruby/comments/2n987g/the_flip_flop_operator_in_ruby/cmbiwt8 http://www.reddit.com/r/ruby/comments/2n987g/the_flip_flop_o...
- Tiquor 11y agoThis is the best FizzBuzz articles that has come out lately.
- VLM 11y agoIt helps having this article next to (nearby) the HN article discussing the 80K static coding violations in Toyota throttle position sensing code, or whatever it was exactly. THIS article didn't get into it very much, but "obviously" you'll have four times the bugs in a highly abstracted 40 part piece of code, than in a much simpler, less capable 10 part piece of code. Reality is bug count never scales at a rate as low as linear with code length of course. At any rate the two HN articles are both better if read at the same time.
- mathieuh 11y agoIt's good, but do you seriously think that's going to get past review? Here's a much better corporate-level version of FizzBuzz: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- Argorak 11y agoI still prefer using symbolic languages for problems of such complexity. Such as... Ruby. https://github.com/sferik/active_emoji/blob/master/samples/fizzbuzz.rb https://github.com/sferik/active_emoji/blob/master/samples/f...
- jessaustin 11y agoBy extracting the modulo operator (%) into its own function, at least we've made the code more self-documenting. If someone else were to read the code and they didn't understand how the modulo operator worked, they could work it out based on the function name. Someone's taking the piss. Would anyone in the "audience" for FizzBuzz code (coders, managers... HR?) really not understand modulo? That seems like kind of the point of FizzBuzz. Sure the whole thing is a satire, but this aspect is sort of straw-mannish.
- placeybordeaux 11y agoDid you finish the article?
- jessaustin 11y agoYes that's why I specifically noted "sure the whole thing is a satire". I just felt that this particular aspect of the satire was unfair.
- placeybordeaux 11y agoApperently I didn't read the comment. I think the point being that fizzbuzz is already a strawman of a programming excersize.
- morgante 11y agoI've met plenty of supposed "coders" who don't know what the modulo operator is. And don't even get me started on managers.
- WatchDog 11y agoAlso see FizzBuzz Enterprise Edition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- sjg007 11y agobrillant.
- wz1000 11y agoHere's a version in Haskell that has the same functionality: fizzbuzz i triggers = map (\x -> fromMaybe (show x) $ liftM mconcat (sequence triggers) x) [i..] fizzbuzz 1 $ [\i -> ["Fizz" | i `rem` 3 == 0] ,\i -> ["Buzz" | i `rem` 5 == 0] ] Its just me playing around and trying to be clever.The way FizzBuzz can be expressed as a Monoid is cool. The rest is just plumbing. mconcat [Just "Fizz", Just "Buzz"] = Just "FizzBuzz" mconcat [Just "Fizz", Nothing ] = Just "Fizz" mconcat [Nothing , Nothing ] = Nothing Note that this requires {-# LANGUAGE MonadComprehensions #-} to compile. Thats for the sugar used when constructing the triggers.
- jacquesm 11y agoI'm sure that Haskell can do better than that in the readability department.
- wz1000 11y agoIt can, I was just trying to be clever :P For one, I don't need to drag monads into function composition: fizzbuzz i triggers = map (\x -> fromMaybe (show x) $ mconcat $ triggers x) [i..] fizzbuzz 1 $ \i -> [["Fizz" | i `rem` 3 == 0] ,["Buzz" | i `rem` 5 == 0] ]
- fizbin 11y agoIf you're going to use the (->) Monad instance, why not: {-# LANGUAGE MonadComprehensions #-} import Data.Maybe (fromMaybe) import Data.Monoid (mconcat) import Control.Applicative ((<*>)) pam = flip map fizzbuzz i trigs = pam [i..] $ fromMaybe . show <*> mconcat . trigs ans = fizzbuzz 1 $ \i -> [["Fizz" | i `rem` 3 == 0] ,["Buzz" | i `rem` 5 == 0] ] main = mapM_ putStrLn $ take 100 ans
- deleted 11y ago[deleted]
- brudgers 11y agoHardcoding 'Fizz' and 'Buzz' inhibits internationalization.
- drostie 11y agoI take serious issue with the "lesson" that this article is trying to teach at the end, which is that you should not generalize your particular problem into something abstract, solve that abstract problem really well, and then solve your particular problem as an instance of that problem. Modeling your problem as FizzBuzz is a good way to model an unrealistically simple problem. FizzBuzz itself is only meant to filter out the vast masses of applicants who are struggling to find anything in the job market and therefore apply to any job they see hoping that someone will recognize them and take pity on them. It's not a realistic starting point. Alan Kay's words are really insightful on this matter; he says that "the right perspective is worth 80 points of IQ." If you can figure out the right way to look at the problem (the right generic problem to solve given your specific constraints) then it's like being much smarter than any ordinary programmer really is. He gives a much more instructive example: the Windows operating system. This thing is millions of lines of code, so much that if you printed it out in textbooks it'd stretch to the top of the Empire State Building. This was produced by a bunch of people doing exactly what Tom Dalling is suggesting: work only on your specific subproblem, do not solve the generic problems of "how do I make an operating system?", etc. There's no intrinsic reason that a graphical operating system needs to be so big that nobody can read it in a lifetime. And the bugs that exist in Windows are undebuggable. With that many different components at play in the greater ecosystem, knowing which two are interacting to cause the problems that plague you requires an unbelievable amount of insight into what the computer is doing when it performs those quirks. I agree with the specific point that software bloat sucks; I'm working with Ext.JS right now and boy is it bloated with internal abstractions that don't make much sense. Fortunately they isolate other people from dealing with those abstractions, but if I were at Sencha developing on the product I'd constantly be wondering "why do we make an 'Operation object' for the thing that the user wants to do? What's the real point of that?" etc.
- phamilton 11y agoThe point I saw (and heartily agree with) is to be deliberate. DRY is an optimization. What is the cost of DRY? What are the costs of not being DRY? I think we frequently fall into the trap of doing DRY "because we're supposed to" rather than on a case by case basis evaluating whether or there is a net expected benefit. That doesn't always mean taking a hard YAGNI line. There are plenty of opportunities for DRY that don't incur a big cost but enable simplicity in future development. It's fairly simple math (though it requires some degree of arbitrary numbers). <Expected cost of refactor (time and added complexity)> vs <Expected benefit (saving future time)> * <Likelihood you will need to update this code> If you know you're most likely going to revisit the codebase in a month and it's a fairly simple refactor then go ahead and do it.
- nakovet 11y agoNow would you consider a smarter move to do the following in an interview: - gem install your-fizzbuzz-package - require 'your-fizzbuzz-package' - puts FizzBuzz.range(1..100) ? My point being why reinvent the wheel.
- MetaCosm 11y agoDidn't make it to the end?
- nakovet 11y agoYes, I read the entire article, maybe I didn't articulate correctly, my point is, given you are in an interview and somebody asks you "Show me factorial please", wouldn't be a smarter move to import a module that something already wrote and just use it? Again, I read the entire article and saw he ended up with a generic solution.
- MetaCosm 11y agoI think HIS point was about premature abstraction and YAGNI. The article was just examples of terrible abstractions... they were intentionally terrible. The "generic solution" was an example of what NOT to do. The article wasn't interview advice, it was advice about avoiding premature abstraction.
- fineman 11y ago> a smarter move [...] The goal is getting the job, or being a smart ass? As an interviewer, I'll put this one to bed. Pick up the white-board marker and start writing. The intern can look up libraries; I want to see if you can understand what we'd be looking for in those libraries. If you can't implement and discuss a simple version of it, odds are that you cannot. If during this process you talk about how you'd be starting a build/buy research cycle at certain points and what that'd look like, as we spec out the problem and build a prototype, that wouldn't be misplaced.
- simonw 11y agoIf an interviewer asks FizzBuzz, it means they want to do a quick sanity check that you can write code to solve a simple problem. Answer the question and the interview can move on to something more interesting. If you try to give a "clever" answer at this point rather than collaborating with the interviewer, it's likely to give a bad impression. A good interview process isn't just looking for people who are strong programmers, it's looking for people who are good engineers - and good engineers are people who collaborate well rather than trying to prove a point at the first available opportunity.
- contravariant 11y agoThat's not really an optimal way to check divisibility though, if you want to be quick try: fizz = (uint)i*2863311531 <= (uint)i; buzz = (uint)i*3435973837 <= (uint)i; Should work for fine for i<=1000. Edit: changed "<" to "<=", otherwise it fails when i=0.
- kazagistar 11y agoHe mentions ruby uses bigintegers, while this assumes something else, right?
- contravariant 11y agoThe above assumes unsigned 32bit integers. It abuses integer overflow. Perhaps I should have stated that more explicitly.
- kelukelugames 11y agoIf I get asked fizzbuzz in an interview then I'm going to drive my interviewer insane with a switch statement. case 0: print "fizzbuzz"; case 1: print 1; case 2: print 2; case 3: print "fizz";
- yandie 11y agoYour solution failed to satisfy the requirements. You need to print the number for 1 and 2.
- kelukelugames 11y agothanks!
- platz 11y agoI still think the "Naïve" implementation is the best one given the actual specification of the problem, and not some made-up specification and assumptions that solve a different problem than the one actually being asked (which may be more interesting, but that is beside the point).
- placeybordeaux 11y agoI thought that was the point of the article.
- simonw 11y agoThat was the conclusion of the article, if you scroll down to the bottom. "The final implementation represents a veritable explosion of complexity".
- doorhammer 11y agoIt was funny to me, because I immediately liked the second version most, but implemented as as function that takes the range of numbers I want to use. The only reason I liked that version more is because it "solves" common "problems" I run into when I'm screwing around with fizzbuzz in new languages. Funny to me because I'm adding a layer of abstraction to handle specific issues I've encountered in the problem space for a question where the problem space is totally synthetic But yeah, as it's asked, I think the first is the best answer to Fizzbuzz
- ufmace 11y agoI think the point is more clearly stated in the TDWTF Soft Coding article[0] Best quotes: > This brings us right into the definition of Soft Coding: the practice of removing “things that should be in source code” from source code and placing them in some external resource. > The whole point of software (hence, the “soft”) is that it can change that it will change. The only way to insulate your software from business rule changes is to build a completely generic program that’s devoid of all business rules yet can implement any rule. Oh, and they’ve already built that tool. It’s called C++. And Java. And C#. And Basic. And, dare I say, COBOL. [0] http://thedailywtf.com/articles/Soft_Coding http://thedailywtf.com/articles/Soft_Coding
- stevewilhelm 11y agoArticles like this one make me wonder what percent of the development community actually uses TDD. Shouldn't it be natural, even expected, to see the tests that drove each iteration of abstraction? I am particularly interested in how one defines and implements tests for scaling and performance requirements like the 'Lazy Generation' example. Now the standard response will be that it's an article (or programming book, or interview question) so for the sake of brevity and clarity we omitted the test. Wouldn't well defined tests help shape the correct amount of generalization and abstraction?
- the_af 11y agoAren't you assuming TDD is a reasonable way to drive the design of algorithms? I would not expect someone to design fizzbuzz-like functions using TDD. (I would expect to see tests, sure, but tests aren't TDD).
- yason 11y agoI'm glad they got rid of the 'puts' calls in the end. It was irking me to naively assume that you would always be asked to print the answer sequence.
- fizbin 11y agoThe ruby quiz did a round of this back after fizzbuzz had already jumped the shark the first time: http://rubyquiz.com/quiz126.html http://rubyquiz.com/quiz126.html I personally thought that my two entries were pretty amusing: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/254139 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/... and http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/254354 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/...
- Shorel 11y agoI only got to the parametrized version in C++ myself. Nice reading.