メタFizzBuzz
- gen_fizzbuzz.pl
#! /usr/bin/perl use strict; use warnings; use constant PI => 4 * atan2(1, 1); use Math::FFT; sub calc_length { my $n = shift; my $mask = 1; while (($n - 1) & ~$mask) { $mask = ($mask << 1) | 1; } return $mask + 1; } sub main { my $s; foreach my $i (1 .. 100) { $s .= [$i, "Fizz", "Buzz", "FizzBuzz"]->[($i % 3 == 0) | ($i % 5 == 0) << 1]; } my @data = unpack("C*", $s); my $n = scalar @data; @data = (@data, @data)[0 .. &calc_length(scalar @data) - 1]; my $fft = Math::FFT->new(\@data); my $coeff = $fft->ddct(); print << 'EOM'; #! /usr/bin/perl use strict; use warnings; use constant PI => 4 * atan2(1, 1); my $n = <DATA>; my @coeff = <DATA>; foreach my $k (0 .. $n - 1) { my $sum = $coeff[0] * 0.5; foreach my $j (1 .. scalar @coeff - 1) { $sum += $coeff[$j] * cos(PI * $j * ($k + 0.5) / scalar @coeff); } printf "%c", int($sum * 2.0 / scalar @coeff + 0.5); } print "\n"; __DATA__ EOM print "$n\n"; foreach my $k (@{$coeff}) { printf "%f\n", $k; } } &main;
これを実行すると、以下のプログラムが得られる。
$ perl gen_fizzbuzz.pl > fizzbuzz.pl
- fizzbuzz.pl
#! /usr/bin/perl use strict; use warnings; use constant PI => 4 * atan2(1, 1); my $n = <DATA>; my @coeff = <DATA>; foreach my $k (0 .. $n - 1) { my $sum = $coeff[0] * 0.5; foreach my $j (1 .. scalar @coeff - 1) { $sum += $coeff[$j] * cos(PI * $j * ($k + 0.5) / scalar @coeff); } printf "%c", int($sum * 2.0 / scalar @coeff + 0.5); } print "\n"; __DATA__ 313 45205.000000 50.764294 -165.956675 249.478163 94.463205 -42.047046 137.718246 209.111882 -149.663591 181.943045 111.630749 -42.636863 0.608121 278.307401 -163.125127 44.902359 150.049709 32.638000 -227.295107 399.322867 14.425217 -193.998248 -118.206471 -456.664292 -112.707493 -19.884377 -208.176709 -182.426475 -70.901505 -89.439483 -273.809621 -48.518645 -246.765972 -279.709301 -76.121350 -88.874974 -241.260653 -91.854384 -108.789924 -158.121206 -154.150749 -46.620651 -174.372002 -72.963170 -115.194829 -69.948509 -107.788859 -32.668747 -127.192102 41.914475 -103.428954 -37.081897 30.849816 40.325971 -176.146932 242.421619 22.442430 -154.832062 217.194620 393.328280 -567.101771 539.531243 1002.001793 -1813.874300 -1027.533983 -3082.906226 912.398334 300.451378 -747.387373 238.371299 363.002434 -367.712101 24.186177 377.270836 -182.490868 -10.173310 207.525863 -11.219355 -177.723766 223.409696 -9.555635 -110.286551 16.809210 142.380228 -211.139600 -78.199062 50.196804 -41.262051 -207.096413 160.050546 -125.638990 -153.473354 -62.698442 136.452001 -399.015227 32.300335 33.334892 -198.454736 -361.845266 521.223031 -458.993511 -204.965072 425.622412 345.453662 -1413.373100 2865.969000 1135.587678 2818.157624 -1516.412487 -2104.082088 744.494362 -990.868195 -776.037726 -132.309238 -256.415480 -880.084717 9.369799 -342.458778 -558.073596 -247.168604 -117.307618 -568.631763 -143.645743 -177.095173 -383.042105 -217.474180 -89.387586 -377.541900 55.079218 -39.031538 -205.429479 -193.764081 30.336008 -208.813477 -143.477004 73.648108 -180.108865 -91.274086 174.045659 -57.168024 -170.855963 143.470642 -44.696740 -126.108870 167.832462 305.213523 -482.429511 899.586068 613.489285 413.279749 -439.670980 -1903.725148 406.136030 -557.801711 -383.495541 -323.152211 58.799433 -617.474686 3.594296 -269.552954 -181.640264 -352.765554 67.002959 -452.652433 84.899462 -331.737110 1.788564 -133.165161 318.297610 -949.065850 4470.193369 663.992487 -213.420189 -913.173674 -797.000201 333.618638 -829.651365 -376.731900 18.755858 -348.537827 -536.248578 204.662512 -363.934895 -365.721413 67.942556 -65.919374 -423.694377 335.092326 -211.813146 13.392186 434.849436 -61.189988 -842.991114 -2026.163581 819.959530 -309.089355 -414.872132 396.018738 132.693967 -402.609715 508.568854 201.754313 -190.032367 405.433451 432.397780 -188.419283 415.558966 511.693671 -40.282845 310.401655 647.980165 28.939196 271.555257 507.565908 149.591730 128.644657 829.581720 186.976438 128.403331 726.699911 362.124627 -32.871243 749.279735 380.929466 -70.279062 548.543578 553.561607 -252.891326 505.594339 581.411622 -359.026317 164.843223 1001.888784 -1353.437374 -684.696075 -2558.401651 1165.267282 754.186778 -76.864479 411.436787 267.299005 165.012949 138.421628 167.306990 97.321595 100.061974 26.306018 125.147828 52.963820 -49.894903 31.443204 68.725785 -154.181690 0.746770 33.250823 -230.369600 -84.145707 83.506105 -150.382545 -81.991056 23.009046 -103.688060 -180.227510 91.045688 -135.612720 -144.238215 25.825913 -34.024845 -240.685974 208.301690 -69.714480 -96.412013 135.374726 250.183693 -332.814057 792.261519 269.545399 896.700490 -1326.730637 -981.024542 219.639438 -553.088234 -95.380805 -95.829656 -112.521496 -203.431360 108.920963 -199.339629 17.099629 17.477961 -3.100148 -98.122058 130.946726 -67.426485 6.442805 28.790979 79.574770 -181.744992 140.918959 110.254128 104.884980 148.818156 22.943471 35.043113 123.248132 24.729382 20.880203 91.498687 53.212943 -17.959559 93.448135 -0.548359 -30.648591 50.717305 24.072496 -80.681267 22.889151 41.225686 -182.306010 -41.519372 -352.270444 -150.730273 146.525442 -96.832501 -46.859844 -35.597657 23.451671 -165.130961 7.682923 -48.566593 -80.896165 -79.377125 38.365263 -188.167575 -89.707767 -5.578370 -131.902205 -241.152990 131.621972 -327.306368 -327.133388 636.887283 168.291315 357.919030 -99.340038 38.621214 51.681114 -32.109799 -3.726304 31.321032 -42.822554 11.399801 13.385410 -4.562241 4.261528 22.156938 -15.885935 5.213571 7.782969 13.742444 -75.496397 12.327892 -132.580440 168.097636 260.801331 -39.644783 147.174456 99.415581 52.139002 51.107841 166.665526 -3.316107 138.914857 209.818033 -11.300179 13.995645 94.368410 21.575195 37.537771 91.427543 68.782938 -38.021621 239.958958 -10.267622 -146.038624 -71.679989 -92.655082 94.814126 -40.652713 19.014071 -13.723059 47.418263 -41.698042 22.081182 -5.383592 55.570638 -66.549714 35.823274 -22.320070 -21.561687 -92.033065 141.567838 -262.237077 57.428136 -111.112891 708.065596 1004.718292 -423.428990 231.567284 -8.430926 46.794235 -107.823341 153.898789 -116.338264 38.720517 -47.116793 58.487480 -98.911331 89.111725 -80.098336 11.292761 -53.628494 33.001533 -122.754929 66.397343 -161.951390 -29.359629 -72.261334 105.142848 -22.850572 -33.133157 -20.152731 25.748503 -110.087374 28.949834 -56.390231 -14.630360 -63.081111 68.221114 -216.625100 0.766961 -97.546215 -51.309808 -235.750057 77.386800 -308.065830 -131.927035 -615.691365 -213.118345 709.563543 -25.709976 52.721922 -30.984166 97.640004 -76.317799 -25.175607 12.195357 -23.302715 -92.880678 3.323743 -22.008296 -102.144434 -19.505878 -11.654629 -93.198876 -59.820310 14.040052 -94.144037 -61.174346 -16.869823 -67.003903 -146.660944 38.495782 -70.409557 -104.351887 -35.080039 14.891739 -158.267222 -48.084951 -25.552651 -142.206386 95.008677 125.289758 -142.567242 29.955379 60.831992 -23.262109 -99.899903 164.358978 -82.081364 -15.723722 169.324262 79.204939 -154.077510 167.343013 62.804994 -46.910734 27.075653 268.659827 -163.989450 133.908065 180.334733 65.268863 -116.416888 571.436237 -98.551376 100.080247 438.791258 583.923700 -637.138013 1990.426202 787.784537
これを実行すると、以下の結果が得られる。
$ perl fizzbuzz.pl
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829FizzBuzz3132Fizz34BuzzFizz3738FizzBuzz41Fizz4344FizzBuzz4647Fizz49BuzzFizz5253FizzBuzz56Fizz5859FizzBuzz6162Fizz64BuzzFizz6768FizzBuzz71Fizz7374FizzBuzz7677Fizz79BuzzFizz8283FizzBuzz86Fizz8889FizzBuzz9192Fizz94BuzzFizz9798FizzBuzz