DEV Community

Juan Julián Merelo Guervós
Juan Julián Merelo Guervós

Posted on

Perl Weekly Challenge week #1 challenge #2: FizzBuzz

Here goes the second first-week challenge.

Write a one-liner to solve the FizzBuzz problem and print the numbers 1 through 20. However, any number divisible by 3 should be replaced by the word ‘fizz’ and any divisible by 5 by the word ‘buzz’. Those numbers that are both divisible by 3 and 5 become ‘fizzbuzz’.

That's me with another Buzz, Lightyear Buzz

OK, here goes the solution. Perl 6 being a functional language, it was not extremely difficult:

say (1..20 ==> map( { ($_ == 15)??"FizzBuzz"!!$_ } ) ==> duckmap( -> Int $_ { ($_ %% 5 )??"Buzz"!!$_} ) ==> duckmap( -> Int $_ { ($_ %% 3 )??"Fizz"!!$_} ));

First thing is that I'm using the rocket operator just for the hell of it. It nicely illustrates how the thing goes, in what direction and what it does. It's actually syntactic sugar for some functions that can be used as methods or take their "target" (note the pun on rocket) as a second argument. map and duckmap are such functions (and most functional functions too). So it's quite adequate. So the three stages of the rocket do this

  • Get 15 out of the way in the firs stage
  • In the second stage, we have a diverse list: numbers and one string. A simple map will have to check first if it's number, and then check if it's divisible. There might be some simple way of doing that, but it's much simple to use the wonderful duckmap, which only maps if it's a duck, hence its name; it passes through if it's not. So let's create a pointy block that can only be applied to Ints, which are substituted.
  • Third stage could be probably golfed down to the second, but it's a rocket and it needs to fly, so let's do the same for the third stage.

Here's what it prints

(1 2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz 11 Buzz 13 14 FizzBuzz 16 17 Buzz 19 Fizz)

Nice, ain't it? Check out the Perl Weekly Challenge site for more wonderful solutions in Perl and Perl 6!

Also check out the first weekly challenge, translating and counting

Top comments (2)

Collapse
 
learnbyexample profile image
Sundeep

Here's a Perl5 one-liner:

$ perl -le 'print join " ", map { $_ % 15 ? $_ % 3 ? $_ % 5 ? $_ : "Fizz" : "Buzz" : "FizzBuzz" } (1..20)'
1 2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz 11 Buzz 13 14 FizzBuzz 16 17 Buzz 19 Fizz

Note that your question states

any number divisible by 3 should be replaced by the word ‘fizz’

but the output shown has 3 and 5 interchanged

Collapse
 
jj profile image
Juan Julián Merelo Guervós

Ah.. Right. Thanks!