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’.
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 wonderfulduckmap
, 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)
Here's a Perl5 one-liner:
Note that your question states
but the output shown has 3 and 5 interchanged
Ah.. Right. Thanks!