この問題はoneがいくつ、twoがいくつと数えたほうが速いです。ただコーディングがひたすらめんどくさいです。
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"), (0, "and")) val maplen = words.map(x => (x._1, x._2.size)).toMap def count_words(n :Int, m :Int) :Int = if(n == 0) // and count_words0(m) else if(n < 10) count_words1(n, m) else if(n < 20) count_words2(n, m) else if(n < 100) count_words3(n, m) else if(n == 100) count_words4(n, m) else count_words5(n, m) // count "and" def count_words0(m :Int) :Int = if(m < 100) 0 else if(m < 200) m - 100 else if(m < 1000) (m / 100 - 1) * 99 + count_words0(m - (m / 100 - 1) * 100) else m / 1000 * 99 * 9 + count_words0(m % 1000) // 1 <= n < 10 def count_words1(n :Int, m :Int) :Int = { def c1() = { val d1 = m % 10 val d2 = m % 100 / 10 m / 100 * 9 + (if(d2 > 1) d2 - 1 else d2) + (if(d1 >= n) 1 else 0) } def c3() = { val d3 = m / 100 % 10 m / 1000 * 100 + (if(n < d3) 100 else if(n == d3) m % 100 + 1 else 0) } def c4() = { val d4 = m / 1000 if(n < d4) 1000 else if(n == d4) m % 1000 + 1 else 0 } c1 + c3 + c4 } // 10 <= n < 20 def count_words2(n :Int, m :Int) :Int = { val r = m % 100 m / 100 + (if(r < n) 0 else 1) } // n = 20, 30, ..., 90 def count_words3(n :Int, m :Int) :Int = { val r1 = m % 10 val r2 = m % 100 - r1 m / 100 * 10 + (if(n < r2) 10 else if(n == r2) r1 + 1 else 0) } // n = 100 def count_words4(n :Int, m :Int) :Int = { val d4 = m / 1000 val r3 = m % 1000 d4 * 900 + List(0, r3 - 99).max } def count_words5(n :Int, m :Int) :Int = List(0, m - 999).max val N = 1000 println (maplen.map(x => count_words(x._1, N) * x._2).sum) for((n, l) <- maplen.toList.sort(_._1 < _._1)) println (n, count_words(n, N))