前回の記事:ズンドコキヨシ with JavaScript
まとめ:ズンドコキヨシまとめ
ECMAScript 2015 (ECMAScript 6) の勉強がてらやってみます。前回とは違い、一回ずつconsole.log
していく方式にします。
##ジェネレータを使う
ES2015から追加されるジェネレータに関しては、こちらの記事が参考になりました。
JavaScript の イテレータ を極める!
JavaScript の ジェネレータ を極める!
ES2015の機能をバリバリ使って書いてみます。
function* zundokoGenerator() {
const ZUN = "ズン";
const DOKO = "ドコ";
const KIYOSHI = "キ・ヨ・シ!";
const ENDSTR = ZUN.repeat(4) + DOKO;
let str = "";
while (!str.endsWith(ENDSTR)) {
let zd = Math.random() < 0.5 ? ZUN : DOKO;
str += zd;
yield zd;
}
yield KIYOSHI;
}
for (let i of zundokoGenerator()) {
console.log(i);
}
使った機能はこちら。
機能 | 説明 |
---|---|
function* |
ジェネレータ関数の定義 |
yield |
値を返しジェネレータを一時停止する |
const |
ブロックスコープ定数宣言 |
let |
ブロックスコープ変数宣言 |
str.repeat(n) |
文字列をn 回繰り返す |
str.endsWith(foo) |
文字列がfoo で終わるかどうか |
for of |
オブジェクトに対し反復処理を行う |
##コードゴルフしてみる
前回の記録は、
for(z="ズン\n",d="ドコ\n",s="";!s.match(z+z+z+z+d);)s+=Math.random()<.5?z:d;console.log(s+"キ・ヨ・シ!")
の95文字、\n
を抜いても91文字でした。ES2015で苦心してやってみたところ……
p=t=>console.log(t[0]);f=n=>Math.random()<.5?f(n+1,p`ズン`):(p`ドコ`,n<4?f(0):p`キ・ヨ・シ!`);f(0)
89文字!完全に記録更新!
また、推奨はされませんが、console.log
の返り値がfalsyな値であることが約束されているなら87文字になります。
p=t=>console.log(t[0]);f=n=>Math.random()<.5?f(n+1,p`ズン`):p`ドコ`|n<4?f(0):p`キ・ヨ・シ!`;f(0)
以下わかりやすくしたコード。
p = t => console.log(t[0])
f = n => {
if (Math.random() < 0.5) {
p`ズン`
f(n+1)
} else {
p`ドコ`
if (n < 4) f(0)
else p`キ・ヨ・シ!`
}
}
f(0)
ズンが出たらカウントを1増やして再起、ドコが出たら、カウントが3以下ならリセットして再起、4以上なら終了してキヨシ。関数を短く書けることによる再起や、テンプレートリテラルのタグ付けが勝因だったと思います。
使った機能はこちら。
機能 | 説明 |
---|---|
=> |
アロー関数(関数の短縮記法) |
`foo` |
テンプレートリテラル |
p`foo` |
タグ付きテンプレートリテラル |
##感想
FizzBuzzのコードゴルフをES2015でやろうとしてあまり短くならなかったことがあるのですが、今回はES2015を使って記録更新出来てとても嬉しいです。
##追記1
f
の呼び出しにもタグ付きテンプレートリテラルを使うことで、もっと短くなりました。
通常版(86文字)
p=t=>0&console.log(t[0]);f=n=>Math.random()<.5?f(n-~p`ズン`):p`ドコ`|n<4?f``:p`キ・ヨ・シ!`;f``
console.log
が確実にfalsy(84文字)
p=t=>console.log(t[0]);f=n=>Math.random()<.5?f(n-~p`ズン`):p`ドコ`|n<4?f``:p`キ・ヨ・シ!`;f``
##追記2
前回の記事(ES2015使わない方)で82文字、記録更新。
##追記3
コメント欄にて1文字更新。
コードゴルフについてはこちらの記事もどうぞ。
jsでズンドコキヨシのコードゴルフ(87byte)