#!/usr/bin/perl
use 5.016;
use warnings;
use overload (
'""' => sub{ $_[0]->string || $_[0]->number },
'0+' => sub{ $_[0]->number },
fallback => 1
);
sub new { bless [ @_[1, 2] ], (ref $_[0] || $_[0]) } sub number { $_[0]->[0] }
sub string { $_[0]->[1] }
sub _fizz_buzz {
my ($o, $n, $s) = @_;
(ref $o eq '_FizzBuzz') ? $o->new($o->number, $o->string . ($o->number % $n ? '' : $s)) :
_fizz_buzz(_FizzBuzz->new($o, ''), $n, $s)
);
}
sub fizz { _fizz_buzz($_[0], 3, 'Fizz') }
sub buzz { _fizz_buzz($_[0], 5, 'Buzz') }
sub gizz { _fizz_buzz($_[0], 7, 'Gizz') }
say buzz fizz 1;
say buzz fizz 3;
say buzz fizz 5;
say buzz fizz 15;
say buzz fizz 998;
say gizz buzz fizz 7;
say gizz buzz fizz 21;
say gizz buzz fizz 35;
say gizz buzz fizz 105;
say buzz gizz fizz 105;
say buzz(fizz(1)) + 2;
say fizz(buzz(fizz(1)) + buzz(2));
say gizz(buzz(fizz(15))) . "XXX";
IyEvdXNyL2Jpbi9wZXJsCnVzZSA1LjAxNjsKdXNlIHdhcm5pbmdzOwoKcGFja2FnZSBfRml6ekJ1eno7CnVzZSBvdmVybG9hZCAoCgknIiInID0+IHN1YnsgJF9bMF0tPnN0cmluZyB8fCAkX1swXS0+bnVtYmVyIH0sCgknMCsnID0+IHN1YnsgJF9bMF0tPm51bWJlciB9LAoJZmFsbGJhY2sgPT4gMQopOwoKc3ViIG5ldyB7IGJsZXNzIFsgQF9bMSwgMl0gXSwgKHJlZiAkX1swXSB8fCAkX1swXSkgfQpzdWIgbnVtYmVyIHsgJF9bMF0tPlswXSB9CnN1YiBzdHJpbmcgeyAkX1swXS0+WzFdIH0KCnBhY2thZ2UgbWFpbjsKCnN1YiBfZml6el9idXp6IHsKCW15ICgkbywgJG4sICRzKSA9IEBfOwoKCXJldHVybiAoCgkJKHJlZiAkbyBlcSAnX0ZpenpCdXp6JykgPwoJCQkkby0+bmV3KCRvLT5udW1iZXIsICRvLT5zdHJpbmcgLiAoJG8tPm51bWJlciAlICRuID8gJycgOiAkcykpIDoKCQkJX2ZpenpfYnV6eihfRml6ekJ1enotPm5ldygkbywgJycpLCAkbiwgJHMpCgkpOwp9CgpzdWIgZml6eiB7IF9maXp6X2J1enooJF9bMF0sIDMsICdGaXp6JykgfQpzdWIgYnV6eiB7IF9maXp6X2J1enooJF9bMF0sIDUsICdCdXp6JykgfQpzdWIgZ2l6eiB7IF9maXp6X2J1enooJF9bMF0sIDcsICdHaXp6JykgfQoKc2F5IGJ1enogZml6eiAxOwpzYXkgYnV6eiBmaXp6IDM7CnNheSBidXp6IGZpenogNTsKc2F5IGJ1enogZml6eiAxNTsKc2F5IGJ1enogZml6eiA5OTg7CgpzYXkgZ2l6eiBidXp6IGZpenogNzsKc2F5IGdpenogYnV6eiBmaXp6IDIxOwpzYXkgZ2l6eiBidXp6IGZpenogMzU7CnNheSBnaXp6IGJ1enogZml6eiAxMDU7CnNheSBidXp6IGdpenogZml6eiAxMDU7CgpzYXkgYnV6eihmaXp6KDEpKSArIDI7CnNheSBmaXp6KGJ1enooZml6eigxKSkgKyBidXp6KDIpKTsKc2F5IGdpenooYnV6eihmaXp6KDE1KSkpIC4gIlhYWCI7Cg==