/Fizz|Buzz/

use v5.12.0;
use warnings;

s/\A(?:[0369]|[147][0369]*(?:[147][0369]*[258][0369]*)*(?:[147][0369]*[147]|[258])|[258][0369]*(?:[258][0369]*[147][0369]*)*(?:[258][0369]*[258]|[147]))*(?:0|[147][0369]*(?:[147][0369]*[258][0369]*)*5|[258][0369]*(?:[258][0369]*[147][0369]*)*[258][0369]*5)\z/Fizzbuzz/,
s/\A(?:[0369]|[147][0369]*(?:[147][0369]*[258][0369]*)*(?:[147][0369]*[147]|[258])|[258][0369]*(?:[258][0369]*[147][0369]*)*(?:[258][0369]*[258]|[147]))+\z/Fizz/,
s/\A[0-9]*[05]\z/Buzz/,
say
for 1 .. 100

3 Comments

my $fizz = grep {
    1 while s![147][258]|[258][147]|[147]{3}|[258]{3}!!g;
    "" eq $_;
} s![0369]!!gr;

This can also be written as a recursive pattern but I didn’t have sufficient chops×persistence to puzzle it out.

use v5.14;
say s{
    ^ (?<a> [0369]* (*PRUNE) )
    (?: (?<b> [147] (*PRUNE) ) (?<B> (?&a) (?: (?&c) | (?&b) (?&C) ) )
      | (?<c> [258] (*PRUNE) ) (?<C> (?&a) (?: (?&b) | (?&c) (?&B) ) )
    )* (?&a) (?<=(\d)) $
}{Fizz$+}rx =~ s/\d*[05]$/Buzz/r =~ s/\D\K\d+//r for 1..100;
Actually that had a bug on 5-digit numbers and it turns out the regex engine doesn't need backtracking control here either.
#!/usr/bin/env perl
use v5.14;
say s{
  ^ (?<a> [0369]* ) (?:
    (?: (?<b> [147] ) (?<B> (?&a) (?: (?&c) | (?&b) (?&C) ) )
      | (?<c> [258] ) (?<C> (?&a) (?: (?&b) | (?&c) (?&B) ) ) )
    (?&a)
  )* (?<=(.)) $
}{Fizz$+}rx =~ s/\d*[05]$/Buzz/r =~ s/\D\K\d//r for 1..shift//100;

Leave a comment

About mauke

user-pic I blog about Perl.