[JS記号プログラミング] 入門したのでFizzBuzzをやってみた

## JS記号プログラミングとは

こちらの記事で紹介されている、JavaScriptで有効な記号を使ってプログラミングを行うというものです。
[JS記号プログラミング入門](https://qiita.com/acid_chicken/items/eeb0b42a1ecbba0c49e3)

## ルール

ルールはこちらの記事で紹介されているルールに従います。
[JavaScriptで記号のみを用いてできるだけ短く英数字を出力する + 記号のみを用いてFizzBuzzをやってみる](https://qiita.com/acid_chicken/items/1c0d6881d7648578e34d)

> 手持ちのブラウザで動作する文法ならなんでも構わない。
外部のJavaScriptの参照はresourceスキームとchromeスキーム（拡張機能を除く）に限る。
次の文字のみを利用すること。
引用符で文字列を括って任意のStringオブジェクトを作成してはいけない。
0x20 - 0x21
  !
0x22 - 0x26
" # $ % &
0x27 - 0x2f
' ( ) * + , - . /
0x3a - 0x40
: ; < = > ? @
0x5b - 0x60
[ \ ] ^ _ `
0x7b - 0x7e
{ | } ~

## FizzBuzz

とても可読性の良いものができました！！！（？？？） :v::v:

```js
_$=[][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]]((!![]+[])[-~[]]+([][[]]+[])[-~-~-~[]]+(!![]+[])[+[]]+($+[])[-~[]]+(!![]+[])[-~[]]+([][[]]+[])[-~[]]+(([][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[-~-~[]<<-~-~[]]+(/"/+[])[-~[]]+(/\\/+[])[-~[]]+((/ /[($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[(-~-~-~[]<<-~-~[])-~[]]+~(~[]+~[]<<-~-~[])+(![]+[])[-~[]]+(/"/+[])[-~[]])()
_$$=[][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]]((!![]+[])[-~[]]+([][[]]+[])[-~-~-~[]]+(!![]+[])[+[]]+($+[])[-~[]]+(!![]+[])[-~[]]+([][[]]+[])[-~[]]+(([][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[-~-~[]<<-~-~[]]+(/"/+[])[-~[]]+(/\\/+[])[-~[]]+((/ /[($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[(-~-~-~[]<<-~-~[])-~[]]+(-~-~-~-~[])+-~-~-~-~-~-~[]+(/"/+[])[-~[]])()+($+[])[-~-~-~-~-~[]]+_$+_$
_$$$=[][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]]((!![]+[])[-~[]]+([][[]]+[])[-~-~-~[]]+(!![]+[])[+[]]+($+[])[-~[]]+(!![]+[])[-~[]]+([][[]]+[])[-~[]]+(([][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[-~-~[]<<-~-~[]]+(/"/+[])[-~[]]+(/\\/+[])[-~[]]+((/ /[($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[(-~-~-~[]<<-~-~[])-~[]]+(-~-~-~-~[])+(-~-~[])+(/"/+[])[-~[]])()+($+[])[-~[]]+_$+_$
__=[]
;$=_=>_<=+([]+[]+-~[]+~~[]+~~[])?(__=[...__,(_%-~-~-~[]?[]+[]:_$$)+(_%-~-~-~-~-~[]?[]+[]:_$$$)||_],$(_+-~[])):__
$(-~[])
```

## 動作結果
<img width="788" alt="スクリーンショット 2020-04-26 23.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528526/ccc98cbe-8aa2-cc51-2e52-2f684df3afc2.png">


## 解説
この6行が何をしているのかを順に説明します。

### 1、2、3行目
文字の生成です。
ここは[チートシート](https://qiita.com/acid_chicken/items/1c0d6881d7648578e34d#%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)を参考にして"Fizz"と"Buzz"を生成してます。

#### "Fizz"
```js 
_$$=[][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]]((!![]+[])[-~[]]+([][[]]+[])[-~-~-~[]]+(!![]+[])[+[]]+($+[])[-~[]]+(!![]+[])[-~[]]+([][[]]+[])[-~[]]+(([][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[-~-~[]<<-~-~[]]+(/"/+[])[-~[]]+(/\\/+[])[-~[]]+((/ /[($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[(-~-~-~[]<<-~-~[])-~[]]+(-~-~-~-~[])+-~-~-~-~-~-~[]+(/"/+[])[-~[]])()+($+[])[-~-~-~-~-~[]]+_$+_$
```

#### "Buzz"
```js
_$$$=[][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]]((!![]+[])[-~[]]+([][[]]+[])[-~-~-~[]]+(!![]+[])[+[]]+($+[])[-~[]]+(!![]+[])[-~[]]+([][[]]+[])[-~[]]+(([][($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[-~-~[]<<-~-~[]]+(/"/+[])[-~[]]+(/\\/+[])[-~[]]+((/ /[($+[])[-~-~-~[]]+(({})+[])[-~[]]+([][![]]+[])[-~[]]+(![]+[])[-~-~-~[]]+(!![]+[])[+[]]+(!![]+[])[-~[]]+($+[])[-~[]]+($+[])[-~-~-~[]]+(!![]+[])[+[]]+(({})+[])[-~[]]+(!![]+[])[-~[]]])+[])[(-~-~-~[]<<-~-~[])-~[]]+(-~-~-~-~[])+(-~-~[])+(/"/+[])[-~[]])()+($+[])[-~[]]+_$+_$
```

### 4行目
結果を格納するための配列を生成しています。

```js
__=[]
```

### 5行目
FizzBuzzロジックの部分です。
よりわかりやすいように改行を入れました。

```js
$=_=>
  _ <= +([]+[]+-~[]+~~[]+~~[]) ?
  (__ = [...__, (_%-~-~-~[]?[]+[]:_$) + (_ % -~-~-~-~-~[] ? []+[] : _$$) || _], $(_+-~[])) :
  __
```

目を凝らすと徐々に見えてくるはずです・・！

```js
var fn = number => {
  return number <= 100 ? 
  (array = [...array, (number % 3 ? "" : "Fizz") + (number % 5 ? "" : "Buzz") || number], fn(number + 1)) :
  array
}
```

ほら！何をやっているか見えてきましたね！
完全にJS記号プログラミングに慣れた証拠です！(上下のソースは、ほぼ同等の内容となります。)

#### ループ判定

```js
_ <= +([]+[]+-~[]+~~[]+~~[])
```

下記のように文字列を生成してから型変換することで100を表現できます。

```js
+([]+[]+-~[]+~~[]+~~[]) // => 100
// ↓
+(""+1+0+0)
// ↓
+"100"
// ↓
100
```

#### FizzBuzz判定と再帰処理
```js
(__ = [...__, (_%-~-~-~[]?[]+[]:_$) + (_ % -~-~-~-~-~[] ? []+[] : _$$) || _], $(_+-~[]))
```

三項演算子は式を置く仕様なので、`()` でまとめて式とし、カンマ演算子で左から評価させます。
先にFizzBuzzの判定結果を配列に格納してから関数を再帰的に実行しています。

### 6行目
関数の実行です。

```js
$(-~[])
```

## 感想
だいぶスッキリ書けて満足です！楽しかったです！
記号プログラミングはいいぞ。