三角関数cosでFizz Buzz
FizzBuzz問題が何度か、ネット上のプログラマやその他IT関係者で流行ったときに大したネタも思いつかずに乗り遅れた感あったわけですが、このたびやっとネタ(?)が思いついたので、エントリを書こうと思った次第です。
ここで、FizzBuzz問題とは1から順に数字を述べていき、3で割り切れる場合は 「Fizz」、5で割り切れる場合は 「Buzz」、両者で割り切れる場合は 「Fizz Buzz」と述べなければならないという言葉遊びです。
[Link]「Fizz Buzz - Wikipedia」
ただこの、並びを再現する出力するプログラムを各言語で作るのは簡単で、ネット上では、いろいろな素晴らしいコードや業界の理不尽な状況をやや自虐気味に風刺する(?)ネタエントリが生み出されています。僕も楽しく拝見させていただいております。
いまさらですが、私も三角関数のcosを(わざわざ)使ったコードを思いつきましたのご紹介します。
JavaScriptコード(抜粋)
<script> function fizzBuzz(n){ with(Math){ var c = cos(2*PI*n/5); var x = (1+2*c) * c + cos(2*PI*n/3); } return (x>3) ? "Fizz Buzz" :(x>2) ? "Buzz" :(x>1) ? "Fizz" :n; } </script> //・・・ ・・・ <script> for (var i=1;i<100;i++){ document.write(fizzBuzz(i)+", "); } </script>
C#コード(抜粋)
static string fizzBuzz(int n) { var c = Math.Cos(2 * Math.PI*n / 5); var x = (1 + 2 * c) * c + Math.Cos(2 * Math.PI * n / 3); return (x > 3) ? "Fizz Buzz" : (x > 2) ? "Buzz" : (x > 1) ? "Fizz" : n.ToString(); } static void Main(string[] args) { Enumerable.Range(1, 100) .Select(fizzBuzz) .Select(s => { Console.Write("{0}, ", s); return s; }) .ToArray(); }
普通に剰余を使うコードよりもまわりくどいので、「どこが面白いんだ!」といわれるかもしれませんが、割り切れるとかどうかという整数の問題に無関係な三角関数を使った式の値に関しての判定で条件を満たしているかどうかがわかるのが面白いと思いませんか。
使用している三角関数の式は
(1+2*cos(2*Pi*x/5))*(cos(2*Pi*x/5))+cos(2*Pi*x/3)
で、グラフは
[Link]「(1+2*cos(2*pi*x/5))*(cos(2*pi*x/5))+cos(2*pi*x/3) - Google 検索」
[Link]「(1+2*cos(2*Pi*x/5))*(cos(2*Pi*x/5))+cos(2*Pi*x/3) - Wolfram|Alpha」
と、まあこんな感じです。
実は、この関数はx=整数では、
xの値 | (1+2*cos(2*Pi*x/5))*(cos(2*Pi*x/5))+cos(2*Pi*x/3)の値 | 整数との比較 |
---|---|---|
15の倍数 | 4 | >3 |
15の倍数でなくて5の倍数 | 2.5 | >2 |
15の倍数でなくて3の倍数 | 1.5 | >1 |
上記以外の整数 | 0 | <1 |
なのです。
というわけで上記のコードでFizzBuzzの条件の判定ができたのです。こんな関数をどうやって作ったのかというと…秘密ですが、関数を2倍するとわかる人にはわかるかもです…