PL/SQLの勉強6 FizzBuzz問題
2回にわたってプログラミングの基本構造を勉強しました。
以下の3個ですね。
- 順次
- 分岐
- 反復
これらを使う、有名な問題があります。
FizzBuzzをやってみましょう
問題です!
- 1〜100までの数字を画面に出力します。
- ただし3の倍数の時は「Fizz」と出力し
- 5の倍数の時は「Buzz」と出力し
- 15の倍数の時は「FizzBuzz」と出力します。
実際に自分で考えて、PL/SQLを書いてみましょう。
こんな感じに出力できればOKです。
いろんな答えがあります
僕の持論を語ります。。。
人間の性格はみんな違うように、
プログラムも書く人によって変わってくると思います。
結果が正しく、オーダー通りであれば
それは正解だと思っています。
あとはどれだけ綺麗に・他の人が読みやすく書けるか…
以上のことを頭の隅に置いておきながら
いくつかの解答例を示してみようと思います。
本質的には同じことをやっているかも知れませんが
許してくださいね♪
解答例① – 超基本系
例えばこんな感じに書きます。
begin
for v_cnt in 1..100 loop
if mod(v_cnt, 15) = 0 then
dbms_output.put_line('FizzBuzz');
elsif mod(v_cnt, 3) = 0 then
dbms_output.put_line('Fizz');
elsif mod(v_cnt, 5) = 0 then
dbms_output.put_line('Buzz');
else
dbms_output.put_line(v_cnt);
end if;
end loop;
end;
「mod」は、割り算の余りです。
つまり3で割った余が0の時…という感じに使えます。
ちょっと注意なのが
最初に「15の余りは?」とやっているところです。
3とか5の方を先にやると上手くいきません。。。
解答例② – 出力は1ヶ所派
前職で先輩だったプログラマーさんは
「同じ処理は1ヶ所にまとめなさい!」という方でした。
それも割とシビアに。。。
今回の問題で言うと、
「出力」は1ヶ所でまとめよ!と言うはずです。
それを満たした回答は以下になると思います。
declare
v_syutsuryoku varchar2(4000);
begin
for v_cnt in 1..100 loop
if mod(v_cnt, 15) = 0 then
v_syutsuryoku := 'FizzBuzz';
elsif mod(v_cnt, 3) = 0 then
v_syutsuryoku := 'Fizz';
elsif mod(v_cnt, 5) = 0 then
v_syutsuryoku := 'Buzz';
else
v_syutsuryoku := v_cnt;
end if;
dbms_output.put_line(v_syutsuryoku);
end loop;
end;
1つ変数を用意するだけでいいですよね!
慣れれば何も難しいことはありません。
解答例③ – 15の倍数判定はしない
FizzBuzz問題は、いろんな縛りプレイをすることがあります。
その中の1つの例が
「15の倍数判定はしないで作ってみて!」です。
こんな感じに書けるかと思います。
declare
v_syutsuryoku varchar2(4000);
begin
for v_cnt in 1..100 loop
v_syutsuryoku := '';
if mod(v_cnt, 3) = 0 then
v_syutsuryoku := 'Fizz';
end if;
if mod(v_cnt, 5) = 0 then
v_syutsuryoku := v_syutsuryoku || 'Buzz';
end if;
if v_syutsuryoku is null then
v_syutsuryoku := v_cnt;
end if;
dbms_output.put_line(v_syutsuryoku);
end loop;
end;
◆6行目…
出力するための変数を初期化していますね。
これが無いとおかしなことになるので、注意が必要です。
◆16行目…
Oracleでは、空文字の判定は「is null」でします。
どうですか?
1個目の例とは変わってきましたね!
解答例④ – 割り算しない
先ほど「いろんな縛りプレイ」があると書きました。
言っておきながら余り思いつかないのですが
思いつく限りで厄介なものが、割り算をしないパターンです。
割り算ができないとなると…
今の私ならこう書くかなぁ…
declare
-- 出力用の変数
v_syutsuryoku varchar2(4000);
-- カウンタを用意する(初期値:0)
v_3 number := 0; -- 3の倍数用
v_5 number := 0; -- 5の倍数用
begin
for v_cnt in 1..100 loop
-- 出力用の変数を初期化する
v_syutsuryoku := '';
-- カウンタを1UPする
v_3 := v_3 + 1;
v_5 := v_5 + 1;
if v_3 = 3 then
v_syutsuryoku := 'Fizz';
-- カウンタを初期化する
v_3 := 0;
end if;
if v_5 = 5 then
v_syutsuryoku := v_syutsuryoku || 'Buzz';
-- カウンタを初期化する
v_5 := 0;
end if;
if v_syutsuryoku is null then
v_syutsuryoku := v_cnt;
end if;
dbms_output.put_line(v_syutsuryoku);
end loop;
end;
自分でもゴチャゴチャになりそうだし
確認もしたかったので、コメント入れましたw
見ての通りカウンタを準備して
その都度0に戻しながら…ってやってます。
FizzBuzz問題って何に使うの?
4つの解答例を書いてみました。
こんなにやって…
FizzBuzz問題って何のために使うものなの?
って思う方もいるかも知れません。
簡単に言うと、こんな感じです。
あなた、簡単なプログラム書けますか?
例えば面接でこう聞かれたとしましょう。
「書けます!」と答えたとして、
じゃあFizzBuzz問題やってみてよ!
と言われた時に書けないでいると
確実に鼻で笑われます。。。
つまりは初級レベルのプログラムは書けるよね?
の確認に使うのに、すごく良い問題なんです!!
以上ですw
どうでしたか?
初めてやる場合は
いい感じの回答が思い付かない人もいると思います。
でもそれで良いと思っています。
いろんなプログラムを見て、覚えて。
分からなかったら調べて。。。
少しずつスキルを上げていけばいいんです!
何となくこんなロジックもあるよ!と思いついたら
実際にトライしてみてくださいね♪
Discussion
New Comments
No comments yet. Be the first one!