Fizz Buzz問題
Fizz Buzz問題ってなんじゃーって人はWikiを参照してください。
https://ja.wikipedia.org/wiki/Fizz_Buzz
プログラミングのほうです。
program fizzBuzz ;
var
i : integer ;
begin
for i := 1 to 100 do
if (i mod 3 = 0) and (i mod 5 = 0) then
writeln ('FizzBuzz')
else if i mod 3 = 0 then
writeln ('Fizz')
else if i mod 5 = 0 then
writeln ('Buzz')
else
writeln (i)
end.
この手の問題は大学のときにあほほど目にしました。
結城浩さんのC言語プログラミングレッスンとかですね。
こういったループ処理と除算、条件分岐の問題が淡々と載っていて
「*で4段のピラミッドを作りなさい」
とかそんなのもよく解いた気がします。
で、このFizzBuzz問題。
「メモリをなるべく使わないように」とか「高速で」とか制約がつくとちょっと自分ももにょりますが、
まぁかけます。
引数が与えられたら?とかっておもったので引数にはこんな制約をつけてみました。
・引数がある場合は1~引数までFizzBuzzの内容で出力する
・引数に小数があった場合、切り上げ
・引数に数字以外や切り上げても1未満のものは「入力値が不正。」と出力
とかでJavaで書いたらこんな感じですかね。
import java.math.BigDecimal;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
public class FizzBuzzMain {
private static final int DEF_VAL = 100;
private static final int ERROR_VAL = -1;
public static void main(String[] args) {
int loopVal = createLoopVal(args);
if (loopVal == ERROR_VAL) {
System.out.println("入力値が不正。");
}
for (int i = 1; i <= loopVal; i++) {
if (i % 5 == 0 && i % 3 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
}
/**
* 出力内容について作成。引数チェックも簡単に行う。
* @param args
* @return
* 未入力:DEF_VAL<BR>
* 小数切り上げて自然数なら入力値<BR>
* 小数切り上げても負数や数字以外ならERROR_VAL
*/
private static int createLoopVal(String[] args) {
if (args.length == 0 || StringUtils.isBlank(args[0])) {
return DEF_VAL;
} else if (NumberUtils.isNumber(args[0])) {
int tmpVal = new BigDecimal(args[0]).setScale(0, BigDecimal.ROUND_UP).intValue();
if (tmpVal <= 0) {
return ERROR_VAL;
} else {
return tmpVal;
}
} else {
return ERROR_VAL;
}
}
}
実際に書いてみてわかるんですが、Validate的なことをどこまでやるかとかちょっと悩みますね。
とはいえ引数なしで単純に1~100まで出力するのであれば
package test;
public class FizzBuzzMain {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
if (i % 5 == 0 && i % 3 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
}
}
こんなんで事足りるでしょう。
普通の問題です。
■FizzBuzz問題が解けないプログラマーがいるらしい
この内容を書こうとおもったきっかけが
【どうしてプログラマに・・・プログラムが書けないのか?】
http://www.aoky.net/articles/jeff_atwood/why_cant_programmers_program.htm
の記事でした。
2007年のものです。
で、ググってみたらそれなりにレアなケースではなく、わりとかけない事例があったりもしたので結構な驚きとともに、
翻って自分の周りにもいる気がします。気のせいだよね?書けるよね、、、?
こういった単純なものがかけなくても職業プログラマーにはなれます。
正直大学時代の自分からすると結構な驚きですが。。。
自分の会社は、自分達で設計して自分達で開発して自分達で保守するので、
「とりあえず動けばいいや」という気持ちでプログラムを書く人は世間に比べて少ないと思います。
後で痛い目を見るのは自分ですしね。
なので多少はこういったことにも気をつかう風土はあると思うのですが、
「とりあえず動けばいい」とかいった観点しかない場合、よく使う関数の使い方は知っていても
このようなアルゴリズム(といっていいかわからないレベルですが)は分からないという場合が多々あると思います。
まぁ使わないことは知らないというものですね。
程度問題ではあって、自分が大学のときにちょっとだけ参加したプログラミングコンテストのような
アルゴリズムもりもりな問題は解けなくてもいい気もしますが、
この程度の問題はプロとしてプログラミングでお金をもらっている以上さらっと解きたいものです。。。
というかこれプログラミングというか論理的思考力みたいなものを問う問題よね。。。
絶対2年もプログラミングに触れていれば
「条件分岐の書き方」
「100回繰り返す書き方」
「割り算のあまりの求め方」
は絶対知っているはずだし、書き方は知らなくてもググれば出てくるし。
それも分からず、FizzBuzz問題が解けないというのは
きっとプログラミングがかけないというか論理的思考力みたいなものがないからだと思います。
フロー図がかけないんですね
べつにコレが解けなくても職業プログラマーとしてお金稼げるかもしれません。
できないことをばかにすることが目的ではなく、おそらく日常の業務でこういった知識を使わないってことなんでしょう。
ただ、プログラマーとして正直ちょっとまずい気がするので仕事内容をもう少しフローチャートを考えたりする仕事もしたほうがいいように正直思います。。。
■小学校でプログラミングが必修になるそうです
プログラミングが必修になるようですね。
これ自体は個人的には歓迎すべきことだと思います。
ただ、まぁたぶんいろいろな人が言っていて、いまさらなことかもしれないですが、
プログラミングで何を身につけさせたいのかですね。
何をやるかはわからないですが、中学1年生は何らかの言語で「Hello,World!!」が全員かけるようになってるんですかね
プログラムに慣れるということが目的なら正直素晴らしいと思います。
プログラムになじみがない人は上のコードの羅列を見ただけで「うげ、、、」ってなるだろうし。
自分が英語のサイト見て「うげ、、、」ってなるのときっと似た感じなんでしょう。
でも書けるようにするということが目的ならその論理的思考力みたいなもの、
それこそ数学とかそんなものをもっとしっかりやってほしいなーって思います。
あとそれこそ日本語。ちゃんと理解できるってのは大事です。
文系だろうが理系だろうがプログラムはかけます。
アルゴリズムの研究とか、それこそ今はやりのディープラーニングとかは理工学をちゃんと勉強しました!
って人しか立ち入れない領域ですが、職業プログラマーとしてお金をもらうのには正直そこまでいりません。
マウスの右クリックを押してコピーしてた人もそういう環境になればプログラムかいてたりします。
目先のアウトプットよりも、ぜひアルゴリズムのフロー図とかで
【1~100まで繰り返して3の倍数では「Fizz」、5の倍数では「Buzz」、両者の公倍数(すなわち15の倍数)では「Fizz Buzz」】
が書けるようになってほしいなー、そういった力をつけてほしいなーって思います。
もちろんJavaのデザインパターンとかは知ってるのはいいことだけど、
こういったFizzBuzz問題がとけないのは問題だなーっておもいました。
(というか本当にこれくらいかけない人いるのか、、、?)

コメント