Skip to content

Instantly share code, notes, and snippets.

@masak
Forked from walkermatt/fizzbuzz.clj
Last active September 10, 2017 03:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masak/b9371625ad85cfe0faba to your computer and use it in GitHub Desktop.
Save masak/b9371625ad85cfe0faba to your computer and use it in GitHub Desktop.
fizzbuzz without conditionals in Perl 6
# 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;
@0racle
Copy link

0racle commented Apr 19, 2016

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.

@mathew-robertson
Copy link

mathew-robertson commented Sep 9, 2017

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 ).

@mathew-robertson
Copy link

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];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment