今回はpaiza x QiitaのCランク問題「Fizz Buzz」をやってみます。
ただ解くだけではつまらないので、3つのアプローチで解いていきましょう。
基礎から発展的な方法をご紹介します。
問題概要
整数 N が入力として与えられます。
1からNまでの整数を1から順に表示してください。
ただし、表示しようとしている数値が、
・3の倍数かつ5の倍数のときには、"Fizz Buzz"
・3の倍数のときには、"Fizz"
・5の倍数のときには、"Buzz"
を数値の代わりに表示してください。
No.1 for文を使う
パッと思い浮かんだのはfor
文を使用することです。一番簡単であり、馴染みのある解き方でしょう。
for (let i = 1; i <= +lines[0]; i++) {
if (i % 15 === 0) {
console.log('Fizz Buzz');
continue;
}
if (i % 5 === 0) {
console.log('Buzz');
continue;
}
if (i % 3 === 0) {
console.log('Fizz');
continue;
}
console.log(i);
}
No.2 再帰関数を使う
ちょっと難しくなりますが、再帰関数を使う方法です。
こちらはfor
文を使用することなく解くことが可能です。
function fizzBuzz(totalCount, currentCount = 1) {
if (currentCount > totalCount) return;
let result = null;
if (currentCount % 15 === 0) {
result = 'Fizz Buzz';
} else if (currentCount % 5 === 0) {
result = 'Buzz';
} else if (currentCount % 3 === 0) {
result = 'Fizz';
} else {
result = currentCount;
}
console.log(result);
fizzBuzz(totalCount, currentCount + 1);
}
fizzBuzz(+lines[0]);
実装自体は簡単で、自分の関数内で自分の関数を呼び出しています。
ただし呼ぶ毎にcurrentCount
を+1していて、最初の関数呼び出し時に与えた数値(totalCount
)より大きくなった場合に処理終了しているだけです。
No.3 ジェネレーターを使用する
これは普段あまり使用しない方法でしょう。
ですがこういった方法もあると知っていれば、いつか役に立つかもしれません。
function* generatorFizzBuzz(num) {
for (let i = 1; i <= num; i++) {
if (i % 15 === 0) {
yield 'Fizz Buzz';
continue;
}
if (i % 5 === 0) {
yield 'Buzz';
continue;
}
if (i % 3 === 0) {
yield 'Fizz';
continue;
}
yield i;
}
}
const generator = generatorFizzBuzz(+lines[0]);
for (const result of generator) {
console.log(result)
}
ジェネレーター関数を使用し、出力結果を生成しておきます。
その後for...of
構文で結果を出力する流れになります。
ちょいとリファクタリング
条件判定が野暮ったいので、三項演算子で書いてみます。
for (let i = 1; i <= +lines[0]; i++) {
const result =
i % 15 === 0
? 'Fizz Buzz'
: i % 5 === 0
? 'Buzz'
: i % 3 === 0
? 'Fizz'
: i
console.log(result);
}
うん、余計に見づらくなってしまった。if
文でやった方がわかりやすいですね。
さいごに
どうでしょうか。
FizzBuzzは他の問題と比べて簡単に解けると思います。しかし、簡単だからこそさまざまなアプローチができて楽しめる問題だと考えています。
皆さんも違ったアプローチでチャレンジしてみてください!