ScalaでProject Euler(31)

Problem 17

Map

Mapをまとめて作るには、キーと値のタプルのリストを使います。

val words = List((1, "one"), (2, "two"), ...)
val maplen = words.map(x => (x._1, x._2.size)).toMap

上は、数 → 文字数というマップを作っています。
あとは1〜1000の文字数を順に数えていけばよいです。

val words = List((1, "one"), (2, "two"), (3, "three"), (4, "four"),
                 (5, "five"), (6, "six"), (7, "seven"), (8, "eight"),
                 (9, "nine"), (10, "ten"), (11, "eleven"), (12, "twelve"),
                 (13, "thirteen"), (14, "fourteen"), (15, "fifteen"),
                 (16, "sixteen"), (17, "seventeen"), (18, "eighteen"),
                 (19, "nineteen"), (20, "twenty"), (30, "thirty"),
                 (40, "forty"), (50, "fifty"), (60, "sixty"),
                 (70, "seventy"), (80, "eighty"), (90, "ninety"),
                 (100, "hundred"), (1000, "thousand"))

val maplen = words.map(x => (x._1, x._2.size)).toMap

def num_length(n :Int) :Int =
    if(n == 0)
        0
    else if(n < 20)
        maplen(n)
    else if(n < 100)
        maplen(n - n % 10) + num_length(n % 10)
    else if(n < 1000) {
        val r = n % 100
        maplen(n / 100) + maplen(100) +
                (if(r == 0) 0 else 3 + num_length(r))
    }
    else
        maplen(n / 1000) + maplen(1000) + num_length(n % 1000)

val N = 2345
println ((1 to N).foldLeft(0)(_ + num_length(_)))