Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

Been through the year 2007'ish thread here about fizzbuzz. Reason: - Just came back from an interview. I had mentioned in my resume that I was doing some sys admin level perl scripting, and one of the interviewers asked me to write a script that would print fizz if the number is divisible by 3, buzz if the number is divisible by 5, and fizzbuzz if it is divisible by both.

I had clearly stated during the interview that I had done perl scripting about 3 years ago, and then didn't much write any scripts, except for a 15 minute fiddle may be once in a month or two.

It did take me about 15-20 minutes to write this script, and I had to look up the documentation (It was stated that I could refer to perldocs). So I came up with the following:

C:\>more newfizzbuzz.pl #!/usr/bin/perl use warnings; use strict; my @stuff = (1..100); my @fizzbuzz = map { ($_ % 3 == 0 && $_ % 5 == 0)?print "fizzbuzz\t": $_ % 3 == 0? print "fizz\t": $_ % 5 == 0?print "buzz\t":print "$_\t" } @stuff;

And here is the output.

C:\>perl newfizzbuzz.pl 1 2 fizz 4 buzz fizz 7 8 fizz + buzz 11 fizz 13 14 fizzbuzz 16 17 fiz +z 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 + 32 fizz 34 buzz fizz 37 38 fizz buz +z 41 fizz 43 44 fizz buzz 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 was asked if there was a better way of doing it and I told that there must be, but that I would have to try it out and see. I was also asked if there was a reason why I didn't use an if/else if statement, and such questions.

So I came up here and did a search for fizzbuzz, and most of the folks have written a oneliner (golf). Just wanted to know if there is something wrong with the script I have given above? Is one liner a preferred way of writing such scripts? Any comments or suggestions would be appreciated.

Note:- Granted that what I've written is not elegant/compact/idiomatic, but just wanted to know if it's so bad that it justifies the weird expression on the interviewer's face? after checking my script :)

Replies are listed 'Best First'.
Re: The FizzBuzz Thing :(
by choroba (Cardinal) on Dec 25, 2015 at 19:28 UTC
    Two concerns:
    1. map is usually used to transform one list into another. What purpose does the @fizzbuzz array serve here? A for-loop would have been more idiomatic, as the returned list is unimportant. In the for-loop, I'd rather use ifs instead of the ternary operators: again, the ternary operator is usually used inside an expression when the returned value is important.
    2. You don't benefit from the fact you can just test for 3 and 5 once, i.e. you're breaking the DRY (don't repeat yourself) principle. There's no need to test for fizzbuzz, you've covered the case in fizz and buzz already.

    For comparison, see my solution to a similar task in the Contest Coding competition.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      DRY? Hmm. I see superfluous variables, print statements in your solution. How about this:

      for (1 .. 100) { say "Fizz" x !($_ % 3) . "Buzz" x !($_ % 5) . "Bizz" x /3/ . "Fuzz" x /5/ || $_ }

        The main point of similar interview questions is (or should be) to provoke discussion. Is it a good practice to use zero time repetition, or negation of a modulo as a number? Etc. There's no "100% right" solution to the question.
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: The FizzBuzz Thing :(
by Your Mother (Archbishop) on Dec 25, 2015 at 19:41 UTC

    choroba made all the right points. Problem is generating an array that doesn’t contain what you think it does and multiple inline print statements where one, without the map, would do. Your answer isn’t bad for someone who is not a hacker and hasn’t touched Perl in 3 years. Good habits and best practices come over time. This was mine from way back when (it does not take advantage of the reuse of the 3/5 to fizz . buzz so it’s not ideal but it is idiomatic :P)–

    #!perl -l print !( $_ % 15) ? "FizzBuzz" : !( $_ % 5 ) ? "Buzz" : !( $_ % 3 ) ? "Fizz" : $_ for 1 .. 100;

      Whether the reuse of 3/5 modulo is ideal or not, is itself a contentious point. Codifying it with three conditions is a straight-forward translation of the three rules in the english problem description and arguably carries the logic in clearest of manner. (I suppose the test reveals a bit about your thinking though — grasp of modulo arithmetic, clever vs readable, etc.)

        :( I enjoy overly idiomatic code and do it for my own nonsense but would not commit that kind of code in production. Harrumph! …well, unless I was mad at somebody… ˇˇˇMarry Christmass!!! More eggnog!

Re: The FizzBuzz Thing =)
by LanX (Saint) on Dec 25, 2015 at 19:38 UTC
    DB<102> for my $i (0..20) { print "$i:\t"; print "fizz" if not $i % 3; print "buzz" if not $i % 5; print "\n"; } 0: fizzbuzz 1: 2: 3: fizz 4: 5: buzz 6: fizz 7: 8: 9: fizz 10: buzz 11: 12: fizz 13: 14: 15: fizzbuzz 16: 17: 18: fizz 19: 20: buzz

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Re: The FizzBuzz Thing :(
by davido (Cardinal) on Dec 26, 2015 at 05:56 UTC

    I have no knowledge of your interview, but if I had been the one interviewing, and if I were to present you with a programming problem such as fizzbuzz, I, most likely wouldn't be looking for a perfect, succinct, or idiomatic solution. FizzBuzz is a problem that can be solved a number of ways. Most common solutions involve a loop, some sort of conditional, some Boolean logic, and understanding of the modulus operator. These are all things that a student in his 2nd week of his first CS course would have had exposure to. An early programming course might ask students to solve the "Making change" problem, which probably involves similar tools.

    I would be looking at the process; can this candidate plan an implement an algorithm? Does this candidate know how to access the documentation for the implementation language? What approach is used for verifying the output? If there's a need for debugging, how is it handled? Does it appear this candidate has a clear and logical thought process? And afterwards, can the candidate explain his solution? Can he make good observations as to any tradeoffs he made in his algorithm? Did he code for clarity, for golf, for aesthetics, for cleverness? Were these styles intentional? How does the discussion go? Is he defensive, or open to talking about his code?

    There's no single solution, and although it might be a red flag if one were to go too far out on the "cleverness" branch, being able to identify the choices made and discuss them comfortably could also win some points.

    An interview is to get to know the individual while also gaining comfort that they can actually do the job. A small programming challenge is only one component of that process.


    Dave

      Hi,

      Thank you for the detailed answer.

Re: The FizzBuzz Thing :(
by BrowserUk (Patriarch) on Dec 26, 2015 at 01:03 UTC

    No comment on "the best solution"; just another way to do it:

    printf "%s\t", ( $_ % 3 ? '' : 'fizz' ) . ( $_ % 5 ? '' : 'buzz' ) || +$_ for 1 .. 20; 1 2 fizz 4 buzz fizz 7 8 fizz + buzz 11 fizz 13 14 fizzbuzz 16 17 + fizz 19 buzz

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: The FizzBuzz Thing :(
by Anonymous Monk on Dec 25, 2015 at 19:58 UTC
    Granted that what I've written is not elegant/compact/idiomatic, but just wanted to know if it's so bad that it justifies the weird expression on the interviewer's face?
    It's just a very simple, even primitive task, so your code should be equally simple (the KISS principle). If I were hiring someone, anything that's not along the lines of
    for ( 1 .. 100 ) { if ( ... ) { ... } else { ... } }
    wouldn't really be acceptable. It's not a test of programming skills, it's a test of common sense (IMO). I'm afraid your code fails it, and it doesn't even show off your programming chops (for reasons already covered by others).

      Whoops,

      Just hoping you ain't the same fellow who interviewed me.

        No, that wasn't I, but
        I was also asked if there was a reason why I didn't use an if/else if statement
        certainly someone like minded. BTW, what did you answer? :)
Re: The FizzBuzz Thing :(
by Anonymous Monk on Dec 25, 2015 at 20:14 UTC

    Respected Monks,

    Please let me know if there's a good book that can set me on the right path.

    PS AnonyMonk (Not me, but my Alter Ego who brought up the point of Common Sense): I do know that there's no such book for common sense, but heck, may be I'll grow some if I go through a good book. :)

Re: The FizzBuzz Thing :(
by Anonymous Monk on Dec 25, 2015 at 19:54 UTC

    Monks,

    Wow, Thanks a lot. I learned a lot today. Tried the map without using @fizzbuzz and it worked. Now going through the suggestions given here. Thank you all. Merry Christmas folks!!

Re: The FizzBuzz Thing :(
by Anonymous Monk on Dec 26, 2015 at 13:35 UTC

    Respected Monks,

    Thank you for all the answers. Kindly request you to please suggest a good Perl Book I can refer to. I don't mind starting from the scratch. Please do suggest.

      "Modern Perl" by chromatic is the best.
        Thank you, but isn't that an advanced level book?