【javascript】演算子なしでFizzBuzzを書く

# 【javascript】演算子なしでFizzBuzzを書く
**※この記事には通常では考えられないような記法が多々登場します**

演算子、使ってますよね？ね？？（こんな記事見てる人なら）
Javascriptにはたくさんの演算子があります。
それを使わないチャレンジです。~~要は自慢したいだけ~~
___
## 演算子の規定
演算子の規定は基本的に[MDN Web Docs](https://developer.mozilla.org/)の[式と演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators)のページを参照しました

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators

主なものは下記のものです（これが全てではないです）
算術演算子：```+``` ```-``` ```*``` ```/``` ```%``` ```**```
比較演算子：```==``` ```!=``` ```<``` ```>```
代入演算子：```=```
論理演算子：```!``` ```&&``` ```||```
三項演算子：```? :```
グループ化：```()```
そして**プロパティアクセス演算子**です
## プロパティアクセス演算子
あまり聞き馴染みのない演算子ですが察しの良い方はもうお気づきでしょう
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓

```console.log()``` ```console["log"]()```
そうですこいつらです。
**チェーン記法**と**ブラケット記法**です。
~~最後まで閲覧していただき、ありがとうございます~~

追記: 「プロパティアクセスは演算子ではないのでは」と指摘されましたが、規定で書いてしまったものは仕方がないので、
## 試し書き
まず一旦FizzBuzzを書いてみる
```javascript
for(let i = 0; i <= 100; i++) {
    if(!(i % 15)) {
        console.log('FizzBuzz');
    } else if(!(i % 5)) {
        console.log('Buzz');
    } else if(!(i % 3)) {
        console.log('Fizz');
    } else {
        console.log(i);
    }
}
```
## 問題点
* チェーン表記が使えない
* 割り算ができない
* 代入やインクリメントができない(forが使えない)
* 正誤判定ができない
## デバッグ
### チェーン表記
一番問題なのが```console.log()```が禁止であるということ
~~どうしよ諦めよっかな、、、~~
<br><br>
そういえば```with```句ある！※非推奨
#### with句とは
ざっくり言うと```()```の中の要素を```{}```内で展開する、、みたいな？
```javascript
with(console) {
    log('Fizz');
    error('Buzz');
}
```
こんな感じ。
とりあえず一番問題だったチェーン表記ができない問題はなんとかなった。
### 繰り返し
**が、** それがかけたとて繰り返しがなぁ、、、
<br><br>
再帰使うか！
```javascript
function main(i) {
    /* 処理 */
    main(i + 1)
} 
```
インクリメントできねぇな、、、
どうしよ
```[1,2,3,...,99,100]```で```for-of```使うとかいけないかな
<br><br><br>
配列の```for-in```配列番号返した気がする？
おお、返した！
```javascript
for(i in ['a','b']) {
    /* 処理 */
}
```
OKこれで100回繰り返す処理は書けた
```javascript
for(i in Array(100)) {
    /* 処理 */
}
```
あれ、動かない、、
どうやら配列内の中身がないと動かないらしい
<br><br>
なら文字化してみる。(2マスのスペースは文字数追加分)
```javascript
for(i in `${Array(100)}  `) {
    /* 処理 */
}
```
出来た！
### 剰余
なら次は、、剰余？
Mathの中にも良いのないしなぁ、、、
<br><br>
n進法の一の位で行ける！
なら
```javascript
Number(i.toString(x).at(-1))
```
を```with```句で書いて
```javascript
with(i) {
    with(toString(x)) {
        Number(at(-1))
    }
}
```
### -1
まさかの```-1```が書けないという事態
```-1```を返してくれる関数、、
<br><br>
```indexOf()```とかだけどまた```with```句、使わないといけないのか、、、
上に```string```が入ってる```with```句があった！
じゃあ
```javascript
with(i) {
    with(toString(x)) {
        Number(at(indexOf))
    }
}
```
### falsyの判定
あとは0の判定は
```javascript
if(/* 余り */) {} else {
    /* 処理 */
}
````
で行けるね！
## 動作確認
```javascript
for(i in`${Array(100)}  `) {
    function mod(x) {
        with(i) {
            with(toString(x)) {
                return Number(at(indexOf()))
            }
        }
    }
    console.log(mod(15))
}
//=> 0 1 2 3 4 5 6 7 8 9 0 1 ...
```
おかしい、
n進数に変換できていない？
<br><br>
あ、```i```が```str```型だからか。

```javascript
for(i in`${Array(100)}  `) {
    function mod(x) {
        with(i) {
            with(toString(x)) {
                return Number(at(indexOf()))
            }
        }
    }
    console.log(mod(15))
}
//=> 0 1 2 3 4 5 6 7 8 9 NaN NaN ...
```
これじゃあ```NaN```まで```falsy```だな、、
（```parseInt(at(indexOf()), x)```にして治しました）
### 0の判定
0で正誤判定するか、、
どうしよ、、、
<br><br>
```switch```って等号じゃん！
でもいっぱい書かないといけないのだるいな、、

```switch(0)```で判定すればいいか！
```javascript
for(i in`${Array(100)}  `) {
    function mod(x) {
        with(Number(i)) {
            with(toString(x)) {
                return parseInt(at(indexOf()), x)
            }
        }
    }
    with(console) {
        switch(0) {
            case mod(15):log('Fizzbuzz');
                break;
            case mod(5):log('Buzz');
                break;
            case mod(3):log('Fizz');
                break;
            default:log(i)
        }
    }
}
// FizzBuzz 1 2 Fizz 4 Buzz ...
```
最初の```0```だけ飛ばさないといけないけど
```switch```文で```0```判定がちょうどできるから、、
## 完成
```javascript
for(i in`${Array(100)}  `) {
    function mod(x) {
        with(Number(i)) {
            with(toString(x)) {
                return parseInt(at(indexOf()), x)
            }
        }
    }
    with(console) {
        switch(0) {
            case Number(i):break
            case mod(15):log('Fizzbuzz');
                break;
            case mod(5):log('Buzz');
                break;
            case mod(3):log('Fizz');
                break;
            default:log(i)
        }
    }
}
```
## 最後のやつ
**最後まで閲覧していただきありがとうございます！**
ブログなんて初めて書いたので(~~にしては内容がおかしい~~)
拙い部分もたくさんあると思いますが、そこは大目に見ていただいて、、、
```for-in```の```in```は演算子ではなく式の一部だっていうどうでもいい知識を得ることができました（笑）
使用を見返すいい機会にはなるんじゃないでしょうか？
```javascript
[is間違った知識] || [hasもっと良い表現] || [esolang好きの変人] ? コメント() : history.go(-1)
```

~~そういえば、周りにesolangとかやっている人がいなさ過ぎて困ってます~~
## おまけ

pythonでも書いてみた

```python
def candiv(x, y):
  for i, v in enumerate(divmod(x, y)):
    if i:
      if v:
        return 0
      return 1

for i in range(1, 101):
  if candiv(i, 15):
    print("FizzBuzz")
  elif candiv(i, 3):
    print("Fizz")
  elif candiv(i, 5):
    print("Buzz")
  else:
    print(i)
```