Hacker News new | past | comments | ask | show | jobs | submit login
Can you beat 99% of programmers? Try the FizzBuzz challenge (trybloc.com)
19 points by jmtame on Dec 14, 2011 | hide | past | favorite | 50 comments



Suppose FizzBuzz were a perfect proxy for programming ability. Some programmers are FizzBuzz-capable, and the rest are FizzBuzz-failures. Members of both groups interview for jobs. A FB-capable programmer goes on three interviews, gets an offer, and works at his job for a couple of years. A FB-failure goes on three interviews, gets no offers (or if he gets an offer, gets fired shortly after), and goes on three more interviews the next week.

The FB-capable average 1.3 interviews/year. The FB-failures average 150 interviews/year. (All numbers are total fabrications, of course.) There don't have to be a lot of FB-failures for them to represent 99% of interview candidates.


You may laugh at the utter simplicity of this test, but I administer this several times a week when I interview candidates.

I am still dismayed at how few programmers can solve this given 30 min (15 for the correct solution, plus 15 for optimizations across instructions and code brevity). It filters out the weak for sure.


I always thought that was some kind of urban myth that programmers made up to make themselves look better.


Unfortunately it is really not, I have a friend who is just transitioning from junior to senior level and he is kind of coming to the realization that the majority of developers are really that bad. I usually look at elitist statements with a bit of septicemic because generally it is an average person trying to make themselves feel better, but in the case of the development world, it really is that bad. It is the reason that we have the 10x'ers.

For example a good developer should be able to solve this problem even if he has never used the technologies involved. It is that simple of a problem. I have never developed in Ruby in my life, 10 minutes on Google gave me all the Ruby API's I needed to complete the challenge. You see a good developer sees the solution and then figures out the API to do what they need it to do. Mastery of the technology is not what makes a good developer, seeing the solutions is where the value of a developer should be measured.


Really? That's depressing as hell. I think I could have done this in Basic on my TI-83 in highschool, and I'm not even a career software developer.


How is it possible that 99% of programmers fail this? What qualifies as a programmer? (Where is that statistic even from...) Does that mean someone with a CS degree? Are the failures stemming from not knowing the general concept, or is it just lack of familiarity with any language (I suppose both are quite horrifying)


The actual quote this is based on roughly said 99% of applicants, which is hardly the same as 99% of programmers.

http://www.codinghorror.com/blog/2007/02/why-cant-programmer...

My own opinion is that if the ratio is this bad by the time they get to the interview, you may not be pre-screening well enough.


It's probably 99% of job applicants. Remember a bad programmer will go to more job interviews than a good programmer, because the bad programmer probably won't get a job. So the success rate of job applicants is not the same as the percentage for all programmers.


I do not know Ruby and I was able to complete the test in under 10 minutes. familiarity with the language should not be an issue with a problem this simple.


I do not know Ruby, but I wanted to see what happened when I clicked next. Without writing any code I clicked "Grade it!" This provided me with the unit test output. I looked at it for a moment and then guessed at a solution that might work using copy and paste and based on the comment in the code. Here it is:

puts ["1", "2", "fizz", "4", "buzz", "fizz", "7", "8", "fizz", "buzz", "11", "fizz", "13", "14", "fizzbuzz", "16", "17", "fizz", "19", "buzz", "fizz", "22", "23", "fizz", "buzz", "26", "fizz", "28", "29", "fizzbuzz", "31", "32", "fizz", "34", "buzz", "fizz", "37", "38", "fizz", "buzz", "41", "fizz", "43", "44", "fizzbuzz", "46", "47", "fizz", "49", "buzz", "fizz", "52", "53", "fizz", "buzz", "56", "fizz", "58", "59", "fizzbuzz", "61", "62", "fizz", "64", "buzz", "fizz", "67", "68", "fizz", "buzz", "71", "fizz", "73", "74", "fizzbuzz", "76", "77", "fizz", "79", "buzz", "fizz", "82", "83", "fizz", "buzz", "86", "fizz", "88", "89", "fizzbuzz", "91", "92", "fizz", "94", "buzz", "fizz", "97", "98", "fizz", "buzz"]

I passed.


I too don't know Ruby and passed. My approach:

1. Google to see if Ruby has a for loop. It does. "for i in 1..100" looks like a good start.

2. Google for a switch or case statement. Don't like what I see. Google for an if/else. Looks good. Guess "if i%15 == 0 ... elsif ... end".

3. Google to make sure the mod operator is indeed %.

Done.


That "for i in 1..100" loop would get you dinged at lots of Ruby shops, since it's not idiomatic. "100.times { }" is the idiom.


It's actually kind of fun to write a program in a language you don't know, just learning by Googling as you go. I did that when I wanted to write some add-ons for Warhammer Online. Someday, I'm going to have to properly learn Lua and its idioms and conventions and then go back and look at my Warhammer stuff and see just how horrible I did.

If anyone wants to laugh at my code, here it is: https://github.com/tzs/WAR-Whom

I also did the same thing with JavaScript. I wanted a calculator for Talisman building in Warhammer Online. At first I was going to do it as an iPhone application. Then I decided a web page would make more sense, and so was going to write it as a Perl CGI application. Then I decided it would make more sense to do it in JavaScript so that my server wasn't doing the work.

That code is here: https://github.com/tzs/WAR-TalismanCalculator

These were fun experiments, but overall I think I prefer to learn the way I learned C. I got K&R, read it, then went to the computer center (this was before personal computers were common), sat down at a terminal, and started hacking out some simple programs, with my K&R at my side. A couple sessions of that cleared up the few things I had misunderstood.

Unfortunately, I've never found a book as good as K&R for any other language I've wanted to learn.

I remember reading an article about "Digital Natives" and "Digital Immigrants". The thesis of the article was that people who grow up in the digital world have a fundamentally different approach to things like learning than do those of us who grew up pre-digital. They are the natives--they grew up with computers, and multitasking, and access to vast amounts of online knowledge. They don't want to learn things by sitting down with a book and reading it through chapter by chapter, and then go out and apply that knowledge. They expect that for any task they wish to accomplish, they can learn what they need when they need it by going to Wikipedia, or Googling, or getting help on IRC, and so on.

When I set out to write my Warhammer Online add-on and the talisman calculator, I was consciously trying to act more like a digital native than a digital immigrant, to see how well it worked. It worked out better than I expected, but not enough to convince me that the digital native approach is better than the digital immigrant approach.


100.times is also wrong (unless you i+1 in your block all the time)

Cleaner, I think is "1.upto(100){ ... }"


I like (1..100).each {} better :)


I don't like clever languages. For loop is good enough :P


My favorite answer. You can even leave out the "" around the numbers. I'm surprised the lower case fizz and buzz passed--the directions definitely say "Fizz" and "Buzz" (I got a 503, so I haven't been able to get to the unit tests).


Or even more tersely:

puts %w(1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97 98 fizz buzz)


Those rules are somewhat different to the ones I learned in HS. My teacher's version mapped buzz to multiples of seven, not three, and also required you to use fizz if there was a five anywhere in the number, and buzz for any number containing a seven. Thus, 17,27,37.. were buzzes, as were 70..79, 170..179, and so on. 57 and 75 were both fizz-buzz by that rule. Numbers with multiple 5s had to use the appropriate number of fizzes, and numbers with multiple 7s had to use the appropriate number of buzzes. Thus, 757 would be "buzz-fizz-buzz".

I've seen the fizz buzz test mentioned a lot lately, and had assumed that it was referring to the somewhat more challenging version I knew. Do people really have that much trouble with this simple version?


Your teacher may have modified the problem so students couldn't just copy-paste a solution off the Internet. Sounds like a good teacher.


This is the well known version AFAIK (I've seen in many times over the years).

I'm actually not that surprised people have trouble with it. Even in my CS program at a decent university, I encountered many students that could still not handle simple programming tasks in advanced courses, and were relying on the internet, cheating and heavily leaning on TAs to get through.


I don't know. I've met a ton of programmers and yes have seen people fail at fizzbuzz. But 99%? that number seems a little high.

Then again, my experience is with students at CMU and developers in Silicon Valley.

The stat still seems kind of far out though...


It took me a while to figure out why mine wasn't working because I wrote [1..100], which is a one-element array with a range in it. Too much Haskell, I guess.

To salvage my dignity, here's the Haskell solution:

    main = mapM_ putStrLn $ map fizzbuzz [1..100]
        where fizzbuzz n | n `mod` 15 == 0 = "FizzBuzz"
                         | n `mod` 3  == 0 = "Fizz"
                         | n `mod` 5  == 0 = "Buzz"
                         | otherwise       = show n


This might be a little offtopic, but I would advise against leaving `console.log` calls in production code, even when there are checks to prevent calling it when the console object is undefined. Commenting those lines out would do the trick, since minification can remove them.

Also I went to the [calculator challenge](http://www.trybloc.com/courses/calculator#/1) and noticed this

    # add(4, 2) => 8
    def add(x, y)
    end
Needless to say the comment should read `=> 6`.

Also, since we are all geeks, here's my Clojure version

    (defn buzziffy [a b x]
	      (cond (and (zero? (mod x a)) (zero? (mod x b))) "FizzBuzz"
	            (zero? (mod x a)) "Fizz"
	            (zero? (mod x b)) "Buzz"
	            :else x))

    (println (apply str (map #(str (buzziffy 3 5 %) "\n")
	                      (range 1 100))))


I passed with this : class FizzBuzz def self.run for i in (1..100) if((i.modulo(3)==0) && (i.modulo(5)==0)) puts "FizzBuzz" elsif(i.modulo(3)==0) puts "Fizz" elsif (i.modulo(5)==0) puts "Buzz" else puts i end end end end

and got this :

"Nice job, you beat the FizzBuzz test! If you believe in the rumors, you are officially better than 99.5% of programmers."

--

I'm new to ruby, is there any way to "optimize" that code? - Edit : I don't know how to format code for HN.


Indent your code with four spaces; that'll make it format properly.

Your solution is pretty close, and honestly, is decent enough. There are some idiomatic shortcuts you could take, though; ranges are objects and expose #each, you can use postfix conditionals, and you can use % instead of #modulo.

Here's how I'd do it.

    (1..100).each do |i|
      print i unless i % 3 == 0 or i % 5 == 0
      print "Fizz" if i % 3 == 0
      print "Buzz" if i % 5 == 0
      print "\n"
    end
(print is like puts, but doesn't append the newline, letting me construct the line piecewise).

This might actually run a wee bit slower than your solution, because all three conditions are evaluated per run, but it's less code and easier to read. Good lead-in to a discussion about code clarity vs optimization.



cool, thanks. :)


The fun thing about these sorts of tests if in figuring out how to do it a little bit differently. For example, I wanted to see if I could do it with a true one-liner (ie, no semicolons) with piecewise construction (ie, no nested ternaries). Here's my solution.

(Yes, it's ugly. But it works!)

    (1..100).each { |i| puts [i % 3 == 0 ? "Fizz" : nil, i % 5 == 0 ? "Buzz" : nil].join.first || i }


1.upto(100){|n|puts [["Fizz"][n%3],["Buzz"][n%5]].inject{|m,e|m=m.nil? ? e:m+=e||""}||n}


NoMethodError: undefined method `first' for "":String in Ruby 1.9.3


My initial solution works in real Ruby, but it didn't work in this demo: http://imgur.com/YBYwN

Apparently, assigning the result of a comparison to a literal breaks this demo.

Edit: Also, bonus points if you can elaborate on why you think my second solution really does work correctly, despite the apparent bug. :)


Submitted a (locally tested as working) program, got "0 errors found" and an error message. The ironing is delicious.

Output:

   <title>Application Error</title>
      <iframe src="https://s3.amazonaws.com/heroku_pages/error.html">
        <p>Application Error</p>
      </iframe>


Some ruby code for those non-rubyists:

  (1..100) do |i|
    if i * 2 == 8 and i + 1 == 5
      puts "foo"
    elsif i + 3 == 9
      puts "bar"
    else 
      puts i
    end
  end
Not the solution, but all the syntax you'll need in there.


Probably should include the modulo operator too (Is it '%' ? I'm not a rubyist)


Part of the FizzBuzz test is to find out if the candidate is aware of modulo. :). But yeah it is %.


Oh man, I didn't even think of that. Such a basic concept...the mind reels. =(


I wouldn't really consider programmer == knows modulus. I only learned of the modulus operator a year or two ago (no formal CS background) and previously have built full scale web applications.


>Can you beat 99% of programmers?

Can we have a title that isn't strongly reminiscent of facebook spam?


I am happy I passed, I was worried I suck. What a great day! :)


I tried just hitting "Grade it" and got this reply:

> Oops, looks like we found 0 errors in your code. Try again and click "Grade it!"

So I guess that means I passed?

(After reloading the page it seemed to work better)


Never really touched ruby before and did it without any help other than checking google for some ruby syntax. I highly doubt 99% of "programmers" can't do this.


"Programmer" is a professional job with little to no barrier to entry, often working for people who have no ability to evaluate the quality of your work objectively.

You would be shocked at some of the people out there who call themselves programmers, and even more shocked at how many of these people have supported themselves for years.


  out = [
    ["FizzBuzz", "Fizz", "Fizz", "Fizz", "Fizz"],
    ["Buzz"],
    ["Buzz"]
  ]
  (1..100).each do | ii |
    puts out[ii % 3][ii % 5] || ii
  end
Thanks!

PS: i am assuming this is the fastest you can do in ruby (but I suspect that blocks are expensive alas)

PS2: passing the test is interesting, having a look at the good and/or best answers would be a decent award for having tried in the first time.


The challenge is insufficiently specified. What sort of spacing am I supposed to put between the number, fizz/buzz, and the next answer? A space? A colon and a space? Does it matter?

I don't know ruby, so I didn't make a response, but these things should be spelled out.


It's not a formal specification, but if you just do what the comments in the code say to do ("puts" fizz/buzz/fizzbuzz/#), that's the passing answer.

I don't know Ruby either, so I looked up the syntax for a for loop, guessed at the conditional (elseif vs elsif vs else if) and used puts for output... and that was all it takes to pass the little test.


It specifies in the comment that you should use puts, which includes a newline between entries in ruby.


I just spend the last 30 minutes to learn enough Ruby to pass the test. There are many ways to do this to get it to pass. Thank heavens for modulo, however.


It's simple without modulo too. Division's just repeated subtraction, so subtract 3 or 5 until you hit 0... if you pass it, it wasn't evenly divisible. Multiple loops instead of one.


If you submit it it runs a comparison below and shows what you output and what it's looking for




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: