ちょい調整fizzbuzz

変数$a,$bが不要になったので削除。
あと、print関数自体が1を返すので、printの後に明示的に1を返していたのも失くした。

my $n = sub{0};
my @fizz = ($n,$n,sub{print 'fizz'});
my @buzz = ($n,$n,$n,$n,sub{print 'buzz'});

my $print_n = sub{print $_[0] + 1};

for(my $i=0;$i<100;$i++){
  $fizz[$i % @fizz]->() + $buzz[$i % @buzz]->() || $print_n->($i);
  print "\n";
}

2の倍数で「piyo」が増えたとき

my $n = sub{0};
my @fizz = ($n,$n,sub{print 'fizz'});
my @buzz = ($n,$n,$n,$n,sub{print 'buzz'});
my @piyo = ($n,sub{print 'piyo'});

my $print_n = sub{print $_[0] + 1};

for(my $i=0;$i<100;$i++){
  $piyo[$i % @piyo]->() + $fizz[$i % @fizz]->() + $buzz[$i % @buzz]->() || $print_n->($i);
  print "\n";
}

さらに改良

my $zero = sub{0};
my $print_n = sub{print $_[0] + 1};

sub create_slot{
  my ($num,$str) = @_;
  my @a = map {$zero} (1..$num-1);
  push @a,sub{print $str};
  return @a;
}

my @fizz = create_slot(3,'fizz');
my @buzz = create_slot(5,'buzz');

my @slots = (\@fizz,\@buzz);

for(my $i=0;$i<100;$i++){
  (grep {$_ == 1} map {$_->[$i % @$_]()} @slots) || $print_n->($i);
  print "\n";
}

2の倍数が増えた時は以下のように@slotsに追加して実行すれば良し。ループ内部については変更せずとも良い。

my @piyo = create_slot(2,'piyo');
my @slots = (\@piyo,\@fizz,\@buzz);

とはいえ、配列をわざわざ用意するのはメモリを無駄づかいするので、まだ改良の余地はありそうだ。