前書き
fizzbuzzについては事前にググってください。
問題
\begin{align}
&\mathbb{N} \stackrel{f}{\to} \mathbb{N} \cup \{fizz, \ buzz, \ fizzbuzz\} \\
&x \in \mathbb{N}に対して \\
&xが3で割り切れる場合:f(x) = fizz \\
&xが5で割り切れる場合:f(x) = buzz \\
&ただしxが3と5で割り切れる場合:f(x) = fizzbuzz \\
&それ以外の場合:f(x) = x \\
&となる関数fを求めよ。
\end{align}
$\mathbb{N}$は1オリジン(fizzbuzzって1から始まるイメージがあるから)
$\mathbb{N} \cap \{fizz, \ buzz, \ fizzbuzz\} = \phi$
$x \neq y, \ y \neq z, \ z \neq x$を満たす$\forall x,y,z \in \{fizz, \ buzz, \ fizzbuzz\}$に対して$x + y \neq z, \ x \times y \neq z$
$\forall x \in \{fizz, \ buzz, \ fizzbuzz\}$に対して$0 \times x = 0, \ 1 \times x = x$とする。
$fizz, \ buzz, \ fizzbuzz$ってなんだよって方は四元数の$i,j,k$と思ってください。
解く
f(x) = g_0(x)x + g_1(x)fizz + g_2(x)buzz + g_3(x)fizzbuzz \\
g_0(x) = \left\{
\begin{array}{ll}
1 & (x \notin 3\mathbb{N} \cup 5\mathbb{N}) \\
0 & (x \in 3\mathbb{N} \cup 5\mathbb{N})
\end{array}
\right. \\
g_1(x) = \left\{
\begin{array}{ll}
1 & (x \in 3\mathbb{N} \setminus 5\mathbb{N}) \\
0 & (x \notin 3\mathbb{N} \setminus 5\mathbb{N})
\end{array}
\right. \\
g_2(x) = \left\{
\begin{array}{ll}
1 & (x \in 5\mathbb{N} \setminus 3\mathbb{N}) \\
0 & (x \notin 5\mathbb{N} \setminus 3\mathbb{N})
\end{array}
\right. \\
g_3(x) = \left\{
\begin{array}{ll}
1 & (x \in 3\mathbb{N} \cap 5\mathbb{N}) \\
0 & (x \notin 3\mathbb{N} \cap 5\mathbb{N})
\end{array}
\right. \\
上記を満たす$g_0, g_1, g_2, g_3$を求めればよい。
h_3(x) = \left\{
\begin{array}{ll}
1 & (x \in 3\mathbb{N}) \\
0 & (x \notin 3\mathbb{N})
\end{array}
\right.
\quad
h_5(x) = \left\{
\begin{array}{ll}
1 & (x \in 5\mathbb{N}) \\
0 & (x \notin 5\mathbb{N})
\end{array}
\right.
と定義すると
g_0 = (1 - h_3)(1 - h_5) \\
g_1 = h_3(1 - h_5) \\
g_2 = h_5(1 - h_3) \\
g_3 = h_3h_5
となるので$h_3,h_5$を求めればよい。
h_n(x) = \lfloor \mid \sin{\frac{2x+n}{2n}\pi} \mid \rfloor
とするとnの倍数で1、それ以外で0になる。
以上より
\begin{eqnarray}
f(x) &=& (1-h_3(x))(1-h_5(x))x + h_3(x)(1 - h_5(x))fizz + h_5(x)(1 - h_3(x))buzz + h_3(x)h_5(x)fizzbuzz \\
&=& x + (fizz - x)\lfloor \mid \sin{\frac{2x+3}{6}\pi} \mid \rfloor + (buzz - x)\lfloor \mid \sin{\frac{2x+5}{10}\pi} \mid \rfloor
+ (x - fizz - buzz + fizzbuzz)\lfloor \mid \sin{\frac{2x+3}{6}\pi} \mid \rfloor \lfloor \mid \sin{\frac{2x+5}{10}\pi} \mid \rfloor
\end{eqnarray}
となる。(展開する必要なかったかな…)
確認用プログラム(ES6)
const f = n => x => Math.floor(Math.abs(Math.sin((2*x+n)/(2*n)*Math.PI)));
const f1 = f(3);
const f2 = f(5);
for (let x = 1; x <= 30; x++) {
const num1 = f1(x);
const num2 = f2(x);
const num = (1-num1)*(1-num2)*x || num1*(1-num2)&&"fizz" || num2*(1-num1)&&"buzz" || num1*num2&&"fizzbuzz";
console.log(x + "\t" + num);
}
実行結果
1 1
2 2
3 fizz
4 4
5 buzz
6 fizz
7 7
8 8
9 fizz
10 buzz
11 11
12 fizz
13 13
14 14
15 fizzbuzz
16 16
17 17
18 fizz
19 19
20 buzz
21 fizz
22 22
23 23
24 fizz
25 buzz
26 26
27 fizz
28 28
29 29
30 fizzbuzz