高井です。今回はショートコーディングで遊んでみたいと思います。
初心者向けの記事です!
ショートコーディングって何?
プログラムをできるだけ短いソースコードで書くことです。
コードゴルフとも呼ばれます。
あの手この手で1byteでも減らすので、最終的にできあがるソースコードの可読性は皆無。
実際に業務でこの技術を使うわけではありませんが(使ったら怒られるようなこともやる)、
無駄な記述をしていないか考えられたり、その言語の仕様を深く理解できたり、ちょっとしたテクニックを知れたり、メリットだらけです。
今回のお題
JavaScriptでFizzBuzz問題をやってみます。
FizzBuzz問題はプログラミング学習でよく使われるお題です。
・1から100までを表示させる
・ただし、3の倍数なら「Fizz」、5の倍数なら「Buzz」と表示させる
・3と5の倍数なら「FizzBuzz」と表示させる
今回はconsole.log
を使って、コンソールに以下のように表示させることとします。
1
2
Fizz
4
Buzz
Fizz
…(中略)…
14
FizzBuzz
16
17
…
普通にプログラミングしてみる
まずは普通に書いてみました。
自分でやってみたい人のために折り畳んでおきます。
ここをクリックして回答例を見る
for(var i = 1;i <= 100;i++)
{
if (i % 3 == 0 && i % 5 == 0){
console.log("FizzBuzz");
}
else if (i % 3 == 0){
console.log("Fizz");
}
else if (i % 5 == 0){
console.log("Buzz");
}
else{
console.log(i);
}
}
いざ、ショートコーディングの世界へ!
さて、これをスタートとして(自分でコーディングした人はそれをスタートとして)
最短のソースコードを目指していきます。
Wikipediaには手法として
- コメントは消去する
- スペースを省略する
- 変数の宣言を省略する
- 関数をなるべく使わないようにする
とあります。
今回の場合、他にもできそうなこととして
-
i % 3 == 0
やi % 5 == 0
をもっと短く書けないか? -
if
やelse if
を減らせないか? -
console.log
の呼び出しを一回にできないか?
などがあります。
これらについて取り組んでみます。
条件文を短く書く
-
i % 3 == 0
やi % 5 == 0
をもっと短く書けないか?
を考えます。
JavaScriptでは条件文に数値を入れたとき、0はfalse、それ以外の数値はtrueとして判定されます。
var x = new Boolean(1); // → true
var x = new Boolean(0); // → false
i % 3
はiで割った余りを返すので、例えば以下のように書くことができます。
if (i % 3){
// 余りが0以外の数値、つまり3の倍数でないときの処理
}
else{
// 余りが0、つまり3の倍数のときの処理
}
これを使って回答例を短縮してみました。
ここをクリックして回答例を見る
for(var i = 1;i <= 100;i++)
{
if (i % 3){
if (i % 5){ // 3の倍数でも5の倍数でもないとき
console.log(i);
}else{ // 5の倍数のとき
console.log("Buzz");
}
}else{
if (i % 5){ // 3の倍数のとき
console.log("Fizz");
}else{ // 3と5の倍数のとき
console.log("FizzBuzz");
}
}
}
if
やelse if
を減らす
次に、if文の書き方について考えます。
ショートコーディング御用達テクニックに三項演算子なるものがあります。
三項演算子はif文を省略して書くことができます。
条件式 ? Trueの処理 : Falseの処理
ので、今回の問題であれば以下のように書くことができます。
i % 5 ? 5の倍数でないときの処理 : 5の倍数のときの処理
回答例の一部を書き直してみました。
ここをクリックして回答例を見る
for(var i = 1;i <= 100;i++)
{
if (i % 3){
i % 5 ? console.log(i) : console.log("Buzz");
}else{
i % 5 ? console.log("Fizz") : console.log("FizzBuzz");
}
}
最初に比べるとかなり短くなりました!
さらに三項演算子は入れ子にすることもできます。
条件式1 ? (条件式2 ? 条件式2がTrueの処理 : 条件式2がFalseの処理) : 条件式1がFalseの処理
これで条件1「3の倍数かどうか」と条件2「5の倍数かどうか」を1行に書けそうです!
ここをクリックして回答例を見る
for(var i = 1;i <= 100;i++)
{
i % 3 ? (i % 5 ? console.log(i) : console.log("Buzz")) : (i % 5 ? console.log("Fizz") : console.log("FizzBuzz"));
}
読めないシロモノになってきました!
console.log
の呼び出しを一回にする
console.log
内で三項演算子を呼び出すことができます。
console.log(i % 5 ? 5の倍数でないときに表示する文字列 : 5の倍数のときに表示する文字列)
括弧が入り乱れていて失敗しそうなところですが、やってみます。
ここをクリックして回答例を見る
for(var i = 1;i <= 100;i++)
{
console.log(i % 3 ? (i % 5 ? i : "Buzz") : (i % 5 ? "Fizz" : "FizzBuzz"));
}
今回の記事ではここまでにして、
スペース、改行、その他省略できる文字(for文の{}
や参考演算子の()
など)を削って仕上げとしたいと思います。
もっと楽しいショートコーディングの世界
というわけで完成したのがこちら!
ここをクリックして回答例を見る
for(i=1;i<=100;i++)console.log(i%3?i%5?i:"Buzz":i%5?"Fizz":"FizzBuzz");
なんと71文字まで切り詰めることができました!
ちなみに最初は223文字。達成感ありますね!
…が!!!なんとベストスコアは62文字らしいです。
その驚きの最短コードについては、こちらの記事で解説されています。
今回解説した内容も被っているところがあります。よく分からなかった方はこの記事も見てみるといいかも。
他の言語でもさまざまなお題でショートコーディングが行われています。
好きな言語、勉強中の言語でやってみましょう!
高井でした