ファンファンのファン問題とは
@yamamoto_hiroya さんの 今更FizzBuzz問題?ファンファンのファン問題やろうぜ
や、
@MAMEO さんの ファンファンのファン問題やろうぜという記事をみたのでC#で実践してみた。
という記事に触発されたのでPHPでこの問題を考えてみました。
特に回数については言及されていませんでしたが、@MAMEO さんの記事に沿って私も10回表示するものとします。
(改行は<br>で行うことにしてみました)
まず普通に考える
<?php
for ($i = 0; $i < 10; $i++) {
echo 'ファンファンファン ファンファンのファン<br>';
}
面白くもなんともありません。
「ファン」を重複して書かないようにしてみる
<?php
for($i = 0; $i < 10; $i++) {
for ($j = 0; $j < 8; $j++) {
switch ($j) {
case 3:
echo ' ';
break;
case 6:
echo 'の';
break;
default:
echo 'ファン';
}
}
echo '<br>';
}
長くなりましたし3とか6とかマジックナンバーが書かれていてダサいことこの上ないです。
ここからはネタ
二重三項演算子を使ってワンライナーで書いてみる
<?php for($i=0;$i<10;$i++){for($j=0;$j<8;$j++){echo $j==3?' ':($j==6?'の':'ファン');}echo '<br>';}
PHPの三項演算子は普通にネストして使おうとすると期待通りに動かない( PHPで三項演算子を二重にするとどうなるか?参照)ため右辺の三項演算子を()で括ることによりネストして使えるようにしています。
ただしバグの温床になりやすいので実務では使用厳禁です。
「ファン」の後ろの文字をサフィックスと捉えてみる
<?php for($i=0;$i<10;$i++){foreach(['','',' ','','の','<br>'] as $s){echo 'ファン'.$s;}}
こちらのコメントをヒントに、サフィックスを配列にしてforeachでループさせてみました。
空の要素が3つもありますが考え方は凄く好きです。
「ファン」を別文字にして置換してみる
<?php for($i=0;$i<10;$i++){echo str_replace('*','ファン','*** **の*<br>');}
汎用性がなさすぎてアレですが一気に短くなりました。
さらに短くする
<?php while(@$i++<10){echo str_replace('*','ファン','*** **の*<br>');}
forをwhileにし、条件自体にインクリメント処理を加えることで5バイト減らすことに成功しました。
@でエラー制御もしてるしここまで来るともう実用性皆無です。
(追記)さらにさらに短くする
<? while(@$i++<10)echo str_replace('*','ファン','*** **の*<br>');
whileブロックが1行なので{}が省略できるとフォロワーさんにアドバイス頂いたのと、ショートタグを有効にすれば<?phpも省略できると気付いたので結果更に5バイト減らすことに成功しました。
(さらに追記)ショートタグとdisplay_errors=offの複合技
<?=str_repeat(str_replace(a,ファン,'aaa aaのa<br>'),10);
@rana_kualu さんのコメントをヒントに、str_repeat()を使用して合わせ技を考えてみました。
56バイト(日本語を2バイトでカウント、文字数だと52文字)まで減らすことができました。
終わりに
初心者の皆様におかれましては短さにこだわらずぜひ読みやすいコードを心がけて頂ければと思います。