はてなキーワード: FizzBuzz問題とは
色々縁が合って学部名に情報が入る大学3―4年生の面倒を見てるんだけど,驚くほど英語が出来ない
一応授業である程度習ったらしいけどコーディング能力は低い.具体的にはFizzBuzz問題解けないくらい
しかしそれ以上に問題があるのは英語と基本的な知識で,例えば次の2つのエラー文がどちらからも何が問題なのかわからない
NameError: name 'Fizz' is not defined
IndentationError: unexpected indent
defineもIndentも単語として知らない以前に,変数と文字列リテラルやインデントを理解できてないからエラーコードでググっても解決できないんだよね
同じ理由でDeepL等で訳しても無理.ただ,ChatGPTとかに説明してもらうとわかるらしい
5人中2人がこのレベルなんだけど,本人の希望通りの業界に就職したら0から叩きこまれるんだろうなって思って子牛を見ている気分になったよ
まずこういうJavaScriptは軽量化するために変数名をやたら短くしたりしなくてもいい改行はしないようにしたりするようなプログラムを通して配布されてるんで、これをまともに読もうとはしなくてもええで。
でだ。DBとも連携するようなウェブサイトを作りたいんだったら今ならPHPかRubyあたりやな。
昔ほめぱげを作っていたことがあるんだったらPHPからやるのが手を着けやすいんやが、個人的にはRubyを勉強してRuby on Railsを使えるようになるのがオススメやな。
何でRubyの方がオススメかっていうとJavaScriptにも手を着ける気があるならRubyの方がJavaScriptへの応用が効くと(俺は)思うからや。
まずは1から100まで画面に表示するとかそれができたらFizzBuzz問題に挑戦するとかいうところからループと変数とifを覚えて、次に関数を覚えて、そこまで出来たらあとは実践あるのみだと思うで。
頑張りや。
具体的に1から15までの例で考えてみる。
集合で考えるとして、集合Aを3の倍数、集合Bを5の倍数とする。
U = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
A = { 3, 6, 9, 12, 15 }
B = { 5, 10, 15 }
A∩B = { 15 }
¬(A∪B) = { 1, 2, 4, 7, 8, 11, 13, 14 }
ベン図は次のようになる。
+-----------U----------+ | | | +---A------+ | | | 3 6 | | | | 9 12 +--+---B---+ | | | |15| | | | +-------+--+ 5 10 | | | | | | | +----------+ | | | | 1 2 4 7 8 11 13 14 | +----------------------+
¬(A∪B) = ¬A∩¬B
よって、FizzBuzz問題は次のように読み替えられる。
表にしてみる。
5の倍数 | 5の倍数ではない | |
---|---|---|
3の倍数 | "FizzBuzz" | "Fizz" |
3の倍数ではない | "Buzz" | 元の数字 |
よくあるコードのスタイルをWikipediaから借りることにして、使用する言語をCとする。
https://ja.wikipedia.org/wiki/Fizz_Buzz
#include <stdio.h> int main(void) { int i; for (i = 1; i <= 100; i++) { if (i % 3 == 0 &amp;&amp; i % 5 == 0) { printf("FizzBuzz92;n"); } if (i % 3 == 0 &amp;&amp; i % 5 != 0) { printf("Fizz92;n"); } if (i % 3 != 0 &amp;&amp; i % 5 == 0) { printf("Buzz92;n"); } if (i % 3 != 0 &amp;&amp; i % 5 != 0) { printf("%d92;n", i); } } return 0; }
ここで、元増田が発想したような「3の倍数の後に5の倍数を判定させて"Fizz"と"Buzz"を連続出力すれば"FizzBuzz"の段は要らないんじゃね?」作戦を発動する。
"FizzBuzz"の判定をごっそり削り、"Fizz"と"Buzz"の条件が同時に起こることを考慮する。
forの終わりに改行するようにする。
#include <stdio.h> int main(void) { int i; for (i = 1; i <= 100; i++) { if (i % 3 == 0) { printf("Fizz"); } if (i % 5 == 0) { printf("Buzz"); } if (i % 3 != 0 &amp;&amp; i % 5 != 0) { printf("%d", i); } printf("92;n"); } return 0; }
プログラミングの問題だけど高校一年生までの数学の考え方で解決できる。嬉しい。
1 から順に数を数えていく。但し、その数が 3 で割り切れるならば数字の代わりに Fizz と、5 で割り切れるなら Buzz と言うゲーム。3 でも 5 でも割り切れる場合は、FizzBuzz の順に言う。
これをプログラミングするのがFizzBuzz問題です。
1から15までの例を考えてみる。
入力 | 出力 |
---|---|
1 | 1 |
2 | 2 |
3 | Fizz |
4 | 4 |
5 | Buzz |
6 | Fizz |
7 | 7 |
8 | 8 |
9 | Fizz |
10 | Buzz |
11 | 11 |
12 | Fizz |
13 | 13 |
14 | 14 |
15 | FizzBuzz |
入力と出力の関係を考えると、入力が定まれば、出力も一意に定まることが分かる。つまり、入力と出力の関係を関数にすることができる。この関数をf(x)とする。
関数f(x)は、入力が3の倍数なら"Fizz"、5の倍数なら"Buzz"、3と5の公倍数なら"FizzBuzz"、その他は入力値を返す。
公倍数は最小公倍数を整数倍した値なので、ある値が公倍数であるかどうか判断するには、最小公倍数で割ってみて、割り切れるかを調べることにする。
3と5の最小公倍数は15なので、15で試しに割ってみて、割り切れるかどうかを見る。
3と5の倍数の判定も、それぞれ、3と5で割り切れるかどうかを見る。
Perlは、上から順に命令を実行する命令型言語なので、3や5の倍数の判定の前に、15の倍数の判定を持ってくる。
逆にすると、15の倍数は3の倍数であり、5の倍数でもあるため、"FizzBuzz"が必要な所が"Fizz"や"Buzz"だけになってしまう。
use 5.024; use warnings; sub f { my ($x) = @_; if (($x % 15) == 0) { return "FizzBuzz"; } if (($x % 5) == 0) { return "Buzz"; } if (($x % 3) == 0) { return "Fizz"; } return $x; } foreach my $i (1..100) { say f($i); }
このへんを参考に。
http://blog.jnito.com/entry/20111013/1318459558
FizzBuzzが解けなかったという中には多分制限時間内に仕様の確定ができないせいってのも
多く混じってる気がする。
数値を1つ与えて、1からその数値までFizzBuzzというパターンだが
入力される数値はどの型で渡されるのか、マイナスや小数点以下や
文字が渡される可能性は考えなくてよいかなども指定する必要があるし、
要件として細かい条件がないFizzBuzz問題を渡したときに、
ttp://www.itmedia.co.jp/enterprise/articles/1004/03/news002.html
このアーティクルを読んだけれども、こういうページに限らずどうしてアルゴリズムが書けないプログラマがボロクソに言われなければならないのかよくわからない。
確かに書けないより書けるほうが優れているというのは正しいと思うけれども、かといって「書けない=劣っている」というのはおかしい。
だいたいFizzBuzz問題に関してはさすがに書けないとヤバイというのはわかるんだけど、こういうプログラマーの資質を問われるのが得意な人はライブラリとかの開発に回ればいいんじゃないだろうか。
例えばRailsとかでもRailsの細部まで把握している人ってどれくらいいるんだろう。Railsとかを使うプログラマに求められる資質はそれこそ世の中にあるライブラリをうまく動かせるようなコードを書ければいいじゃないか。だから、ドキュメントを読んだり、常にいろんなライブラリの動向にアンテナをめぐらせて、そういうのに合わせてリファクタリングが出来る程度であればみんながみんな麻雀のアルゴリズムが書けたりする必要はないのではと思う。
でも僕自身はプログラマじゃないんですけどね。
あと、この問題もいずれやってみようとは思う。
私は、流行りのSNSとやらをわりとぞんざいに使っているので、
誰であろうと基本的には全て承認するようにしている。
そのせいか、タイムライン上にいつの間にかへんちくりんな人間がいることも多い。
今日はその一例をここに記したいと思う。
彼はプログラミングに精通しているようで、どうやら情報系の学校に通う学生らしい。
彼はよく、流行りらしい関数型言語(Haskell?)やらアセンブル言語等の話題を取り上げ、
これがああなってこうで・・・等と、恐らく的確なのであろうコメントを発する。
最近の学生は勉強熱心であり意識も高いのだな、と思わせるには十分であった。
仕事をほんの少し楽にする為のこまいスクリプト程度なら書くこともある程度での知識を持つ人間である。
そんな彼の観察を時偶に続けていたところ、
彼がとあるウェブ上のプログラミングコンテストに挑戦した、という旨の発言が目に入った。
いつも難しいアルゴリズムや先進的なコーディングについて語る彼のことだから、
さぞかし優秀な成績なのだろう、と期待してコンテストのウェブサイトにアクセスし、彼の固有名で検索にかけた。
コンテストは4つの問題が出題される形式であり、それぞれ難度に差がつけられている。
1つは中学生でもコードの書き方さえ知っていれば解けるであろう問題。
1つはFizzBuzzを基本とし、それに些細な応用を付与した問題。
1つは前述のエイトクイーン問題から更に発展させた上で、高度な数学的思考を求める問題。
彼の結果は、初問正解のみであった。
提出されたコードは、会期を過ぎると誰でも閲覧が可能になる為、
彼のコードを覗いてみることにした私は、そこで更におかしな笑いがこみ上げた。
彼は、FizzBuzzがほぼ全く書けていなかった。
それどころか、基本的なループ処理や、型の扱いが出来ておらず、
素人の私から見ても、これがちんぷんかんぷんなコードであることは一目瞭然であった。
以前、彼はHaskellの話題に言及する中で逆FizzBuzz問題についても述べていた気がする。
確かに、私もそんな事が要求される場面があれば悩むだろうな、とその記事を読み感想を覚えたが、
彼は逆FizzBuzzどころかFizzBuzzすらマトモに記述できないのである。
「圏論が出来ないヤツは将来、プログラマーとしても技術者としても失格」
「構造体同士の四則演算は全メンバに同一の演算子を適用するのかな?」
彼は、一体何なのだ?
http://anond.hatelabo.jp/20070508170219
もっと上手いやり方があるんだろうなぁ。
$i3=1; $i5=1; $flag=0; for($n=1;$n<101;$n++){ if($i3==3 && $i5==5){ echo "FizzBuzz¥n"; $i3=1; $i5=1; }else{ if($i3==3){ echo "Fizz¥n"; $i3=1; $flag=1; }else{ $i3++; } if($i5==5){ echo "Buzz¥n"; $i5=1; $flag = 1; }else{ $i5++; } if($flag==0){ echo $n."¥n"; } $flag = 0; } }
※一部全角化(&¥<)
なんか色々レスがついて嬉しいですねw
FizzBuzz問題って一般的に、3の倍数と5の倍数以外の場合は数字を表示しないと駄目だよ
それは知りませんでした。
後、def文の中で再帰してるけど、これ、馬鹿でかい数入れたらメモリ使い切らないか?
Phythonは詳しくないから、嘘言ってるかも知れないけど
他には、何も15で場合分けしなくても、改行しなければ3の倍数と5の倍数とそれ以外で済むから
剰余演算の回数が減る
この辺はいかにも興味が無い領域ですねw
メモリは多分使い切ると思いますが、使い切った場合とかめんどくさくて考えたくないです。
他には、何も15で場合分けしなくても、改行しなければ3の倍数と5の倍数とそれ以外で済むから
剰余演算の回数が減る
これも興味ないですね…。計算回数って、数学(数理モデル)を計算機に乗せたから出てきた問題で、実用上は重要だけど数学としてはどうでもいいなあって思っちゃいます。
これひらめいた人はえらい。
文系でもその気になれば身につくの?
情報科学って
何とかなると思うよ。
wikipediaの情報工学の「基礎的な理論」とか「ソフトウェア技術」とかを一通り読んで、
「そういうものがあるんだ」と引き出しに確保しておく。理解するのは年単位の後回しでも十分。
何かプログラム言語を使って、Fizzbuzz問題とかの簡単な課題を解く。
手っ取り早く仕事にしたいなら、JavaでDBを使ったWEB掲示板でも作ってみてもいい。
入門サイトなんて世の中にあふれてるから、学習コストは低いお!!
http://www.itmedia.co.jp/bizid/articles/0711/07/news012.html
"田口元の「ひとりで作るネットサービス」探訪「twitterMobile」はどうやって生まれたのか"を読んでいて湧き出た感情を発露したくなった。
素晴らしいソフトウェアを生み出せるプログラマはそれ相応の評価を受けるべきだが、WEBプログラマというのはレベルと評価が噛み合っていなくて気持ちが悪い。
あくまでリンク先は対象者が絶賛されているようなものではなく、どっちかというとamachang氏やmala氏との絡みで取り上げられていることはわかる。それでも、ただのHTMLの下請け作業を"マークアップエンジニア"といい、真剣に半年も勉強すれば到達出来るレベルで"サービス開発者"として持ち上げる土壌があることが、どう考えてもおかしい業界だと感じる。もちろん、そういう段階を経て有能なプログラマが生まれることは大いにあるだろうが、WEBプログラマの敷居は低い分だけに、業界直結のネット上にレベルの低い人間が取り上げられやすすぎだろ。そしてはてブを見ると、それを仲間内で持ち上げてる。こんな状態では、レベルの低い馴れ合いでしかない。
自分は別業種においてプログラミングは道具の1つとして使っているレベルであるが、本当に評価されるべきプログラマというのは、そんな自分程度ではどうやっているのかわからない事を魔法のようにやってのける連中の事だ。こういう人間は誰でもは真似できない技術の持ち主だから、プロと言える。
その一方で、身につく期間も技術の交代も早いインターネット上で、小手先だけのWEBプログラマが表に出てくる現状。FizzBuzz問題を必死に解いて、さも簡単な事のように振る舞っている連中とかいるんじゃないのか?
いくつか考えてみた
(問1)高階関数と再帰関数を必ず使って数値を要素とするリストの要素の総和を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
(問2)二つの引数をとり二つのうち大きいほうを返す関数と高階関数、再帰関数をつかって数値のリストの最大値を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
というのは簡単すぎるか?簡単すぎるなら
(問3)高階関数と再帰関数を必ず使ってある数値に5を足し、10かけて2で割った数を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
こっちの方がいいかな。でもトリッキーすぎる気もする。
一応問題を出したので、SchemeとPythonで自分で想定している答えを書いておいた。はてなではSchemeが人気のようなので、あまり知らなかったけど関数言語ではSchemeで書いておいた。Pythonで書くのはSchemeだけだとわかりにくいので、なにかスクリプト言語で書いておこうと思ったから。Rubyの方が人気なので、はじめはRubyで書こうと思ったけど挫折した。だれかRubyで書いてくれないかな・・・。コードオブジェクトってなによ。というか関数はオブジェクトなのに引数にできないの?なんで?(以下疑問と愚痴の嵐なので略)Perlは古株が多くてユーザー数も多そうだけど、・・・その・・・無理です・・・。あの言語仕様はやる気がしない。ぶっちゃけ理解できない。Pythonを知らないひとは多そうだけど、知らなくてもSchemeよりは感じは掴めると思うのでPythonでも書いておくことにした。
http://anond.hatelabo.jp/20071110215936
http://anond.hatelabo.jp/20071110220132
これで大部分のひとがこの問題に興味をもたなくて解答するひとがいなくても、興味を持ったひとは安心だね!
追記:
問3で次のは無しとしておきたい。
(define continuous-apply (lambda (lst obj) (cond ((null? lst) obj) (else (continuous-apply (cdr lst) ((car lst) obj)))))) (define plus5 (lambda (num) (+ num 5))) (define times10 (lambda (num) (* num 10))) (define divide2 (lambda (num) (/ num 2))) (define plus5-times10-divide2 (lambda (num) (continuous-apply (list plus5 times10 divide2) num))) (plus5-times10-divide2 2)
def continuousApply(lst, obj): if lst: return continuousApply(lst[1:], lst[0](obj)) else: return obj def plus5(num): return num + 5 def times10(num): return num * 10 def divide2(num): return num / 2 def plus5_times10_divide2(num): return continuousApply([plus5, times10, divide2], 2) plus5_times10_divide2(2)
http://blogs.wankuma.com/episteme/archive/2007/11/08/106927.aspx
かなりテキトー。エラー処理とかしない。
package Animal; sub new { bless { cnt => 1 } , $_[0] } sub Sound { printf "%s\n", $_[0]->{voice} x $_[0]->{cnt} } sub SetCount { $_[0]->{cnt} = $_[1]; $_[0] } sub SetVoice { $_[0]->{voice} = $_[1]; $_[0] } package Dog; use base qw/Animal/; sub new { $_[0]->SUPER::new->SetVoice('Wan') } package Cat; use base qw/Animal/; sub new { $_[0]->SUPER::new->SetVoice('Nya-') } my $animal; $animal = Dog->new; $animal->Sound; $animal->SetCount(3); $animal->Sound; $animal = Cat->new; $animal->Sound;