条件演算子を使う1
「条件演算子」とは「?:」を使い、「真偽値 ? 真の時の値 : 偽の時の値」と書く演算子です。値を3つ取るので「三項演算子」とも呼ばれます。この条件演算子を使えば、「if」文のような処理を1行で書くことができます。例えば、以下のような「if」文は、以下のような条件演算子の処理に置き換えられます。
var a = true;
var b;
if (a) {
b = "真";
} else {
b = "偽";
}
var a = true; var b = a ? "真" : "偽";
この方法を使うことで、これまで「function」や「eval」で書いてきた処理を、短く書くことが可能です。それでは書いてみましょう。分かりやすい順に、いくつか書いてみます。
(i%15==0) ? 3 : ((i%5==0) ? 2 : ((i%3==0) ? 1 : 0))
(i%15==0)?3:(i%5==0)?2:(i%3==0)?1:0
i%15?i%5?i%3?0:1:2:3
さて、最後の「可能な限り詰める」では、「==」がなくなっています。JavaScriptでは、「0」は「false」、「0以外」は「true」として扱うことができます。そのため「i%15!=0」は「i%15」に置き換えることが可能です。
さて、条件分岐を使った解法には、実はもう1種類あります。そこで、その方法も紹介します。レベル3以降を解くために必要な発想になります。
条件演算子を使う2
問題文では、「[i, "fizz", "buzz", "fizzbuzz"][/*★穴埋め位置★*/]」のように、「[i, "fizz", "buzz", "fizzbuzz"]」という配列に対して、添え字「0」「1」「2」「3」を与えるようにしています。そして、「"fizz"」のときは「1」、「"buzz"」のときは「2」、「"fizzbuzz"」のときは「3」を要求しています。
ここで注意しなければならない点は、文字列「"fizz"」と「"buzz"」を結合した文字列が「"fizzbuzz"」であることです。この関係を式で書くと、「"fizz"+"buzz"="fizzbuzz"」です。この結合の関係は、対応した数値「1+2=3」と同じです。このように、文字列と数値には「対応関係」があります。
この対応関係が分かれば、条件演算子を使って他の書き方ができることに気づきます。「"fizz"」のときは「1」、「"buzz"」のときは「2」を取得して、「"fizzbuzz"」のときはその合計値を求めるという方法です。それでは実際にコードを書いてみましょう。
(i%3==0?1:0)+(i%5==0?2:0)
(i%3?0:1)+(i%5?0:2)
ずいぶん短くなりました。19文字です。というわけで、次はレベル2に移っていきましょう。レベル2では、これまで利用していた「条件分岐」が一切利用できなくなります。ここからが、コードパズルの真骨頂になっていきます。
レベル2:条件分岐を使わずにFizzBuzz
レベル2以降は、条件分岐を使わずに「FizzBuzz問題」を解いていきます。「そんなこと、どうやってできるんだ?」と思われるかもしれません。しかし、JavaScriptでは、この処理は比較的簡単にできます。それは、JavaScriptの仕様が以下のようになっているからです。
-
真偽値を数値演算する → 「
true」の場合は「1」、「false」の場合は「0」になる -
数値を真偽値演算する → 「0」の場合は「
false」、「0以外」の場合は「true」になる
この仕様を駆使すると、先ほどよりもさらに短いコードで、目的の処理を実行できます。それでは実際のコードを見ていきましょう。
剰余を真偽値にして数値に変換
まずはシンプルな「==」で比較する方法です。
比較の結果得た真偽値は、「+」や「*」を使って数値演算することにより、「true」の場合は「1」、「false」の場合は「0」に変換できます。
下記の計算では、3で割り切れる場合は「1」、5で割り切れる場合は2倍して「2」を得ています。そして、3の倍数と5の倍数の両方に該当する場合は「1+2=3」で「3」の値を得ています。
(i%3==0)+(i%5==0)*2
次は「==」よりも短い、「<」で比較する方法です。「==」よりも、比較用の演算子が、1文字分短くなっています。
(i%3<1)+(i%5<1)*2
最後は「!」を使い、数値を真偽値として「反転」して利用する方法です。剰余が「0」の場合は「false」とみなして、そこから反転して「true」を得ます。剰余が「0以外」の場合は、「true」とみなして、そこから反転して「false」を得ます。これらの真偽値は、数値演算で「1」「0」に変換できます。
少し説明が複雑ですが、実際のコードを見てみましょう。
!(i%3)+!(i%5)*2
15文字になりました。どうですか、ついてこれますか? それでは次は、禁止文字が一気に増えるレベル3を見ていきましょう。
