ショートコーディングで遊ぼう

高井です。今回はショートコーディングで遊んでみたいと思います。

:::note info
初心者向けの記事です！
:::

# ショートコーディングって何？
プログラムをできるだけ短いソースコードで書くことです。
コードゴルフとも呼ばれます。

あの手この手で1byteでも減らすので、最終的にできあがるソースコードの可読性は皆無。

実際に業務でこの技術を使うわけではありませんが（使ったら怒られるようなこともやる）、
無駄な記述をしていないか考えられたり、その言語の仕様を深く理解できたり、ちょっとしたテクニックを知れたり、メリットだらけです。

# 今回のお題
JavaScriptでFizzBuzz問題をやってみます。

FizzBuzz問題はプログラミング学習でよく使われるお題です。

https://ja.wikipedia.org/wiki/Fizz_Buzz

・1から100までを表示させる
・ただし、3の倍数なら「Fizz」、5の倍数なら「Buzz」と表示させる
・3と5の倍数なら「FizzBuzz」と表示させる


今回は`console.log`を使って、コンソールに以下のように表示させることとします。

```
1
2
Fizz
4
Buzz
Fizz
…（中略）…
14
FizzBuzz
16
17
…
```

# 普通にプログラミングしてみる
まずは普通に書いてみました。
自分でやってみたい人のために折り畳んでおきます。

<details><summary>ここをクリックして回答例を見る</summary>

```javascript
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);
	}
}
```
</details>

# いざ、ショートコーディングの世界へ！
さて、これをスタートとして（自分でコーディングした人はそれをスタートとして）
最短のソースコードを目指していきます。

[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B4%E3%83%AB%E3%83%95)には手法として
+ コメントは消去する
+ スペースを省略する
+ 変数の宣言を省略する
+ 関数をなるべく使わないようにする

とあります。

今回の場合、他にもできそうなこととして
+ `i % 3 == 0`や`i % 5 == 0` をもっと短く書けないか？
+ `if`や`else if`を減らせないか？
+ `console.log`の呼び出しを一回にできないか？
などがあります。
これらについて取り組んでみます。

### 条件文を短く書く
+  `i % 3 == 0`や`i % 5 == 0` をもっと短く書けないか？

を考えます。
JavaScriptでは条件文に数値を入れたとき、**0はfalse、それ以外の数値はtrue**として判定されます。

```javascript
var x = new Boolean(1); // → true
var x = new Boolean(0); // → false
```

`i % 3`はiで割った余りを返すので、例えば以下のように書くことができます。
```javascript
if (i % 3){
	// 余りが0以外の数値、つまり3の倍数でないときの処理
}
else{
	// 余りが0、つまり3の倍数のときの処理
}
```

これを使って回答例を短縮してみました。
<details><summary>ここをクリックして回答例を見る</summary>

```javascript
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");
    }
  }
}
```
</details>

### `if`や`else if`を減らす
次に、if文の書き方について考えます。
ショートコーディング御用達テクニックに**三項演算子**なるものがあります。

三項演算子はif文を省略して書くことができます。
```javascript
条件式 ? Trueの処理 : Falseの処理
```

ので、今回の問題であれば以下のように書くことができます。
```javascript
i % 5 ? 5の倍数でないときの処理 : 5の倍数のときの処理
```

回答例の一部を書き直してみました。

<details><summary>ここをクリックして回答例を見る</summary>

```javascript
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");
  }
}
```
</details>

最初に比べるとかなり短くなりました！

さらに三項演算子は入れ子にすることもできます。
```javascript
条件式1 ? (条件式2 ? 条件式2がTrueの処理 : 条件式2がFalseの処理) : 条件式1がFalseの処理
```
これで条件1「3の倍数かどうか」と条件2「5の倍数かどうか」を1行に書けそうです！

<details><summary>ここをクリックして回答例を見る</summary>

```javascript
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"));
}
```
</details>

読めないシロモノになってきました！

### `console.log`の呼び出しを一回にする
`console.log`内で三項演算子を呼び出すことができます。
```javascript
console.log(i % 5 ? 5の倍数でないときに表示する文字列 : 5の倍数のときに表示する文字列)
```

括弧が入り乱れていて失敗しそうなところですが、やってみます。
<details><summary>ここをクリックして回答例を見る</summary>

```javascript
for(var i = 1;i <= 100;i++)
{
  console.log(i % 3 ? (i % 5 ? i : "Buzz") : (i % 5 ? "Fizz" : "FizzBuzz"));
}
```
</details>

今回の記事ではここまでにして、
スペース、改行、その他省略できる文字（for文の`{}`や参考演算子の`()`など）を削って仕上げとしたいと思います。

# もっと楽しいショートコーディングの世界
というわけで完成したのがこちら！

<details><summary>ここをクリックして回答例を見る</summary>

```javascript
for(i=1;i<=100;i++)console.log(i%3?i%5?i:"Buzz":i%5?"Fizz":"FizzBuzz");
```
</details>

なんと71文字まで切り詰めることができました！
ちなみに最初は223文字。達成感ありますね！

…が！！！なんとベストスコアは**62文字**らしいです。

その驚きの最短コードについては、こちらの記事で解説されています。

https://qiita.com/obake_fe/items/041715068665dc94aac4

今回解説した内容も被っているところがあります。よく分からなかった方はこの記事も見てみるといいかも。

他の言語でもさまざまなお題でショートコーディングが行われています。
好きな言語、勉強中の言語でやってみましょう！

高井でした:golf: