はじめに
あまり馴染みがなさそうな「カリー化」を使ってFizzBuzzを書いてみたいと思います。
FizzBuzz問題とは
一応説明しておくと、FizzBuzz問題とは
1から100まで(?)数字を1つずつカウントしていき、3の倍数だけのときは「Fizz」を、5の倍数だけのときは「Buzz」を、3と5両方の倍数(公倍数)のときは「FizzBuzz」を、それ以外のときは数字をそのまま出力するプログラムです。
プログラマ志願者を本当にコードが書ける人かどうか見分けるための有名なプログラミングの問題で、面接でFizzBuzzを書かされることもあるらしい。
「Ruby FizzBuzz」でググった明日が面接のプログラマ志願者は変態コードじゃなく普通のを探すんだっ・・・!
カリー化を使ってFizzBuzz書くとこんな感じ
closure = (lambda do |a, b, i|
case 0
when i % a + i % b
puts "FizzBuzz"
when i % a
puts "Fizz"
when i % b
puts "Buzz"
else
puts i
end
end).curry
dump = closure.call 3, 5
1.upto(100) {|i| dump.call i}
FizzBuzz出力するところは「15で割って余りが0」という判定でもいいですね。実際、15で割っているFizzBuzzの回答例もググれば見つかりますし。
そうするとこうなる。
closure = (lambda do |lcm, a, b, i|
case 0
when i % lcm
puts "FizzBuzz"
when i % a
puts "Fizz"
when i % b
puts "Buzz"
else
puts i
end
end).curry
dump = closure.call 15, 3, 5
1.upto(100) {|i| dump.call i}
【おまけ】
プログラマ志願者: FizzBuzzできました(ドヤァ)
面接の人: お!早いですねぇ!
プログラマ志願者: (えへへ・・・、昨日の夜がんばって覚えたからな)
面接の人: うん、このプログラムは完璧です
プログラマ志願者: ありがとうございます!(これは採用きまりだな!楽勝楽勝!)
面接の人: あの、このプログラムについて質問いいですか?
プログラマ志願者: はい!なんでしょうか
面接の人: なんで15で割りました?
プログラマ志願者: えっ・・・?
面接の人: なんで15で割って余りを求めました?
プログラマ志願者: えっと・・・
面接の人: 「FizzBuzzを出力するとき」がなぜ「15で割り切れるとき」なんですか?
プログラマ志願者: それは・・・
面接の人: ・・・
プログラマ志願者: ・・・
面接の人B: あのーちょっといいですか? 15はどこから出てきたんです?
プログラマ志願者: ・・・
面接の人A: どこから15が出てきたんだ!?なにもないところから出てきたとは言わせんぞ!
プログラマ志願者: ヒィィィぃ!
面接の人A: ・・・なにも取って食おうってんじゃない
面接の人A: だが、このFizzBuzzプログラムを書いたのは紛れもなく君だろう?
面接の人A: なぜFizzBuzzを出力するときが15で割り切れるときなのか、説明していただけませんか?
プログラマ志願者: ・・・・・・それは・・・
プログラマ志願者: 掛け算です・・・!
面接の人B: フハッ!
プログラマ志願者: ぼくはっ・・・3と5を掛け算しました…!
面接の人A: ハーーーーッハッハ!血迷って滅多なことを言い出したわ!
面接の人C: 「3と5を掛けた」…と?
面接の人D: ほっほっほっ。これはこれは…。おもしろいですねぇ
面接の人E: イ~~~ヒッヒッヒッ…
面接の人F: そうら、本性が現れたぞい
面接の人A: 静粛に!どうかみなさん静粛に!
面接の人A: ・・・コホン
面接の人A: 「3と5、両の数字を掛け合わせ、その結果を以て15の根拠とする。」
面接の人A: ・・・それが汝の答えという理解でいいかな?
プログラマ志願者: そ、それは・・・
面接の人B: 慎重に答えたまえ。次の君の答えで私たちは君の採用の可否を決める
プログラマ志願者: ・・・・・・!
面接の人B: 呆れたものだ・・・!君は自分で書いた簡単なFizzBuzzプログラムの説明も満足にできないのか・・・!?
プログラマ志願者: うぅっ・・・!じゅ、15は・・・掛けざ・・・
オレ: ちがう、そうじゃないんだ!待ってくれ!
プログラマ志願者: オレ君!?
面接の人A: なんだキサマ!出て行け!面接中だ!
オレ: うるさい!心配でもう見ちゃいれないよ!いいか、聞いてくれ!
オレ: FizzBuzzを出力するときは「3と5の両方の倍数で割り切れるとき」、
オレ: それは言い換えれば「3と5の最小公倍数で割り切れるとき」なんだ!
オレ: つまり、3と5の最小公倍数が15の根拠なんだっ・・・!!
面接の人A: ちょっと待て!認めん!認めんぞ!
オレ: なぜだ、認めてくれ!
面接の人A: いや、認めん!
オレ: なぜだ!
面接の人A: 「3と5の最小公倍数が15であること」はどうやって導いた!?
オレ: うぐっ・・・
面接の人A: フハハハ、それみたことかペテン師め!もっともらしいことを
オレ: 倍数だ
面接の人A: …なに?
オレ: 3と5を比べて数が大きいほう、つまり「5」の倍数を、 5, 10, 15… と小さい方から数えていく・・・
オレ: そして、最初に3で割り切れた5の倍数こそが「3と5の最小公倍数」であり、それが15だったんだ!
オレ&プログラマ志願者: これが15の根拠だ!くらえ!