use v5.36; use utf8;

my %h = ( 3=>'Fizz', 5=>'Buzz', 7=>'Boom/Woof/Pop', 8=>'Zing', 11=>'Whack', 13=>'Chop' );

sub 割り切れる($n, $d){ 0 == $n % $d }
sub 桁に含む個数($n, $d){ scalar (() = $n =~ /$_/g) } # $n =~ tr/$d//r

sub 割り切れれば変換($n, @s){ join '', map{ $h{$_} if 割り切れる($n, $_) } @s }
sub 桁に含むなら変換($n, @s){ join '', map{ $h{$_} if 0 < 桁に含む個数($n, $_) } @s }

sub Classic{ map{ 割り切れれば変換($_, 3, 5) or $_ } @_ };
sub Digits{ map{ 桁に含むなら変換($_, 3, 5) or $_ } @_ };
sub Boom{ $h{7} = 'Boom'; map{ my $n = $_;
     join('', map {$h{$_} if 割り切れる($n, $_) or 0 < 桁に含む個数($n, $_)} 3,5,7) or $n} @_ };
sub Woof{ $h{7} = 'Woof'; map{ my $n = $_;
     join('', map {割り切れる($n, $_) and $h{$_} . $h{$_} x 桁に含む個数($n, $_)} 3,5,7) or $n} @_ };
sub Pop_Whack{ $h{7} = 'Pop'; map{ 割り切れれば変換($_, 3,5,7,11) or $_ } @_ };
sub Pop_Whack_Zing_Chop{ $h{7} = 'Pop'; map{ 割り切れれば変換($_, 3,5,7,11,13) or $_ } @_ };

# test main
do { my ($func, @args) = @$_;
   say "@{[$func->(@args)]}" }
 for [\&Classic, 1...15], [\&Digits , 1...15, 35], [\&Boom , 1...15, 7539], [\&Woof , 1...15, 35, 303],
 [\&Pop_Whack, 1...15, 1155], [\&Pop_Whack_Zing_Chop, 1...15, 120120];


※closureや関数の部分適用などOOPSやFunctional的な仕組みを使ってみようかと思ったけど、使うまでもなかった