-
-
Save masak/b9371625ad85cfe0faba to your computer and use it in GitHub Desktop.
# fizzbuzz without conditionals in Perl 6 | |
# Simple pattern matching using multi subs | |
sub fizzbuzz($n) { | |
multi case($, $) { $n } | |
multi case(0, $) { "fizz" } | |
multi case($, 0) { "buzz" } | |
multi case(0, 0) { "fizzbuzz" } | |
case $n % 3, $n % 5; | |
} | |
use Test; | |
is fizzbuzz(1), 1; | |
is fizzbuzz(3), "fizz"; | |
is fizzbuzz(5), "buzz"; | |
is fizzbuzz(6), "fizz"; | |
is fizzbuzz(7), 7; | |
is fizzbuzz(15), "fizzbuzz"; | |
# Test from 1 to 100 | |
is-deeply [fizzbuzz $_ for 1..100], | |
[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"]; | |
done; |
Just stumbled across this gist today. I too played around with pattern-match style fizzbuzz in p5 and p6 when I saw pattern matching in other languages. Of various implementations, this is one of my favourites... I'm not sure it's lighter, but it's interesting for it's use of the %%
operator, and then stringifying the Bools so they can be 'matched' against correctly
sub fizzbuzz ($n) {
given $n %% 3, $n %% 5 {
when ~(True, True ) { "fizzbuzz" }
when ~(True, False) { "fizz" }
when ~(False, True) { "buzz" }
$n
}
}
The localisation could be moved to the parameters if you wanted.
Like I said, probably not lighter because of the coercion going on, but I like how the True/False relates to the questions being asked (ie. is $n divisible by...). It reads much like the description of the fizzbuzz problem itself.
As per "Get Kata" by Keven Henney... https://youtu.be/_M4o0ExLQCs?t=3044
my @fizzes = (("","","Fizz") xx Inf).flat.lazy;
my @buzzes = (("","","","","Buzz") xx Inf).flat.lazy;
my @words = @fizzes Z~ @buzzes;
my @numbers = [1...*];
sub fizzbuzzer($a,$b) { $a ?? $a !! $b }
my @fizzbuzz = zip(@words, @numbers, :with(&fizzbuzzer));
say @fizzbuzz[0..20];
All lazy until say'd.
Could have used "&max", but this sub{} makes it clearer as to the intent of the zip-reduction of first-param over second-param (and not relying on '1' < 'a' ASCII ).
A variation of the first and seconds examples, but relying on the the type-system and runtime to implement the conditional [ aka: using multi-dispatch subs ].
subset Fizz of Int where { .grep: -> $v { $v %% 3 && $v % 5 } };
subset Buzz of Int where { .grep: -> $v { $v %% 5 && $v % 3 } };
subset FizzBuzz of Int where { .grep: -> $v { $v %% 15 } };
subset Not-a-fizz-buzz of Int where { .grep: -> $v { $v % 3 && $v % 5 } };
multi sub fizzbuzz(Fizz) { say "Fizz" };
multi sub fizzbuzz(Buzz) { say "Buzz" };
multi sub fizzbuzz(FizzBuzz) { say "FizzBuzz" };
multi sub fizzbuzz(Not-a-fizz-buzz $v) { say $v };
fizzbuzz($_) for [1..100];
Yet another version, slightly lighter: