一日一処: ワンラインで判定するJavaScriptのFizzBuzz
FizzBuzz
FizzBuzzは、ピラミッド生成と同じくらい、基礎的な技能を測るプログラム課題として有名だと思う。特に、このような固有名詞で呼ばれるくらいであるため、これ自体のWikipediaのページが存在する。Wikipediaには、飲み会やドライブの雑談にも用いられるとあるが、遭遇したことがない。後述されているプログラムのほうが馴染みがある。今後機会があれば、飲み会やドライブ中にでも導入してみようと思う。
FizzBuzzのルール
至って簡単だ。どこかに、3に関連する数字を言うたびにおかしくなる人間がいたように、FizzBuzzでは、3の倍数にてFizz、5の倍数にてBuzz、両方と一致する15の倍数の際にはFizzBuzzと唱えるというルールだ。
1
2
Fizz
4
Buzz
Fizz
といった具合で、Wikipediaにもある通り、そこまで難しいプログラムにはならない。
まずは基本的な記述
最初にJavaScriptを用いて、基本的な記述でこれを実行してみる。1から始まり数値の最大は100とする。
for (let i = 1; i <= 100; i++) {
let message = ''
if (i % 3 === 0) {
message = 'Fizz'
}
if (i % 5 === 0) {
message += 'Buzz'
}
console.log(message === '' ? i : message)
}
先の例の通り100までFizzBuzzを交えながら出力してくれる。最後の出力部分も上と同じく条件分岐でも良かったが、三項演算子を用いてシンプルにした。
緩やかに短縮していく
せっかく三項演算子を用いたのだから、他の箇所でも用いなければ、もったいない。そのため次は、このように修正してみた。
for (let i = 1; i <= 100; i++) {
let message = i % 3 === 0 ? 'Fizz' : ''
message += i % 5 === 0 ? 'Buzz' : message
console.log(message === '' ? i : message)
}
これでも十分短くなっただろう。
書き換わったプログラムを見ると、複数変数に代入しているのも整理できそうだ。
for (let i = 1; i <= 100; i++) {
const message = (i % 3 === 0 ? 'Fizz' : '') + (i % 5 === 0 ? 'Buzz' : '')
console.log(message === '' ? i : message)
}
短いコードに一歩近づいた。過去のピラミッド建造では、ここから、繰り返し構文の中に全部押し込めるという荒業を見せた。今回は、もう少し、モダンな書き方でワンラインを目指す。最後にこう書き換えれば、1行でシンプルなコードとなる。
console.log(Array(100).fill().map((_,i)=>((++i%3?'':'Fizz')+(i%5?'':'Buzz'))||i).join('\n'))
非常に短く、そして美しくなったのではないだろうか。特に三項演算子を条件を反転させたり、息数から得た配列番号を加算する点などは、芸術点が高いように思える。
Discussion