SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

あなたはどこまで解き進められる?
「FizzBuzzダンジョン」でコードパズル

JavaScriptで遊ぶ、禁止文字つき制限コーディング

ダウンロード fizzbuzz_dungeon.zip (4.3 KB)

条件演算子を使う1

 「条件演算子」とは「?:」を使い、「真偽値 ? 真の時の値 : 偽の時の値」と書く演算子です。値を3つ取るので「三項演算子」とも呼ばれます。この条件演算子を使えば、「if」文のような処理を1行で書くことができます。例えば、以下のような「if」文は、以下のような条件演算子の処理に置き換えられます。

「if」文で書く
var a = true;
var b;
if (a) {
    b = "真";
} else {
    b = "偽";
}
条件演算子で書く
var a = true;
var b = a ? "真" : "偽";

 この方法を使うことで、これまで「function」や「eval」で書いてきた処理を、短く書くことが可能です。それでは書いてみましょう。分かりやすい順に、いくつか書いてみます。

カッコを使って分かりやすく書く(51文字)
(i%15==0) ? 3 : ((i%5==0) ? 2 : ((i%3==0) ? 1 : 0))
少しカッコを取り除く(35文字)
(i%15==0)?3:(i%5==0)?2:(i%3==0)?1:0
可能な限り詰める(20文字)
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"」のときはその合計値を求めるという方法です。それでは実際にコードを書いてみましょう。

「==」を使って分かりやすく書く(25文字)
(i%3==0?1:0)+(i%5==0?2:0)
「==」を除いて短く書く(19文字)
(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」の値を得ています。

「==」で比較(19文字)
(i%3==0)+(i%5==0)*2

 次は「==」よりも短い、「<」で比較する方法です。「==」よりも、比較用の演算子が、1文字分短くなっています。

「<」で比較(17文字)
(i%3<1)+(i%5<1)*2

 最後は「!」を使い、数値を真偽値として「反転」して利用する方法です。剰余が「0」の場合は「false」とみなして、そこから反転して「true」を得ます。剰余が「0以外」の場合は、「true」とみなして、そこから反転して「false」を得ます。これらの真偽値は、数値演算で「1」「0」に変換できます。

 少し説明が複雑ですが、実際のコードを見てみましょう。

「!」で計算(15文字)
!(i%3)+!(i%5)*2

 15文字になりました。どうですか、ついてこれますか? それでは次は、禁止文字が一気に増えるレベル3を見ていきましょう。

次のページ
レベル3:演算子の制限がある中で計算

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7546 2013/12/25 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー