[Scala] 無限リストを使ったFizzBuzz

  • このエントリーをはてなブックマークに追加

最近Scalaの勉強を始めたので、FizzBuzzを作ってみました。
Fizz Buzz - Wikipedia

無限リストを利用し、条件式を追加することなくFizzとBuzz以外にも約数と出力文字列のペアを無数に追加することが可能になっています。

再帰関数を使用していますが、無名関数は自身を直接呼び出す事が出来ないので、Yコンビネータで代用しています。
不動点コンビネータ - Wikipedia

object Main extends App {
    def fizzBuzz(n: Int) {
        // 約数と文字列のリスト
        val ms = List[(Int, String)](
            (3, "Fizz"),
            (5, "Buzz")
        )

        // Yコンビネータ
        def Y[A, B](f: ((A => B), A) => B, x: A): B = f((y: A) => Y(f, y), x)

        // タプルを無限リスト化
        val _ms = ms.map((t: (Int, String)) =>
            Y((f: Int => Stream[String], x: Int) => (if (x % t._1 == 0) t._2 else "") #:: f(x + 1), 1)
        )

        // 無限リストから取り出しと連結を必要数行う
        0 until n map (x => _ms.foldLeft("")((a, b) => a + b(x)) match {
            case "" => (x + 1).toString()
            case x => x
        }) foreach (println)
    }

    fizzBuzz(20)
}

うーん、関数型言語は難しい。

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。




コメントを残す