2011-06-05
FizzBuzz ジェネレータ
と勉で、FizzBuzz 知らないよって人が数人いたので、どうしてプログラマに・・・プログラムが書けないのか? に有名な和訳があるので読んでみてください。
問題は
1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
です。まだ、if文を習っていない1年生は分からないと思います(次回説明します)が、2年生以上には、スラスラと書けて欲しいです。
それだけのための記事にするのはもったいないので、OCaml, Scala, Python, Hakell で書きました。
OCaml で FizzBuzz
let iota n m = let rec loop a i = if i > 0 then loop (i::a) (i-1) else a in loop [] (n-m+1) let genFizzBuzz n = List.map (fun x -> match (x mod 3, x mod 5) with (0, 0) -> "FizzBuzz" | (0, _) -> "Fizz" | (_, 0) -> "Buzz" | _ -> string_of_int x) (iota n 1) let _ = List.iter (fun x -> print_endline x) (genFizzBuzz 100) (* 古いバージョン *) let _genFizzBuzz n = List.map (fun x -> match x with x when x mod 15 == 0 -> "FizzBuzz" | x when x mod 3 == 0 -> "Fizz" | x when x mod 5 == 0 -> "Buzz" | x -> string_of_int x) (iota n 1)
Scala で FizzBuzz
object FizzBuzz { def genFizzBuzz(n: Int) = { for(x <- 1 to n) yield { (x % 3, x % 5) match { case (0, 0) => "FizzBuzz" case (0, _) => "Fizz" case (_, 0) => "Buzz" case _ => x.toString } } } def main(args: Array[String]) = { for(x <- genFizzBuzz(100)) { println(x) } } // 古いバージョン def _genFizzBuzz(n: Int) = { for(i <- 1 to n) yield { i match { case x if x % 15 == 0 => "FizzBuzz" case x if x % 3 == 0 => "Fizz" case x if x % 5 == 0 => "Buzz" case x => x.toString } } } }
Python で FizzBuzz
def genFizzBuzz(n): def f(i): if i % 15 == 0: return "FizzBuzz" elif i % 3 == 0: return "Fizz" elif i % 5 == 0: return "Buzz" else: return str(i) for i in range(1,n+1): yield f(i) for a in [x for x in genFizzBuzz(100)]: print a
無駄に 内包記法で書いてあるけど、よく忘れるから。
Haskell で FizzBuzz
module Main where genFizzBuzz = map f [x | x <- [1..]] where f n = case (n `mod` 3, n `mod` 5) of (0, 0) -> "FizzBuzz" (0, _) -> "Fizz" (_, 0) -> "Buzz" _ -> show(n) main = do putStrLn $ foldr (\ x y -> x ++ ('\n':y)) "" (take 100 genFizzBuzz) -- 古いバージョン _genFizzBuzz = map f [x | x <- [1..]] where f n = case n of n | n `mod` 15 == 0 -> "FizzBuzz" n | n `mod` 3 == 0 -> "Fizz" n | n `mod` 5 == 0 -> "Buzz" n -> show n
camlspotter さんにご指摘いただいたので、ちょっと修正しました。
