0017.hs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. {-
  2. If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
  3. If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
  4. NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
  5. -}
  6. import Data.Char
  7. import Data.Function
  8. (|>) = (&)
  9. -- Round Down to Nearest Ten
  10. rd2nt :: Int -> Int
  11. rd2nt x
  12. | x < 10 = 0
  13. | x < 20 = 10
  14. | x < 30 = 20
  15. | x < 40 = 30
  16. | x < 50 = 40
  17. | x < 60 = 50
  18. | x < 70 = 60
  19. | x < 80 = 70
  20. | x < 90 = 80
  21. | x < 100 = 90
  22. | x >= 100 = rd2nt (mod x 100)
  23. digit_to_name :: Int -> String
  24. digit_to_name 0 = ""
  25. digit_to_name 1 = "one"
  26. digit_to_name 2 = "two"
  27. digit_to_name 3 = "three"
  28. digit_to_name 4 = "four"
  29. digit_to_name 5 = "five"
  30. digit_to_name 6 = "six"
  31. digit_to_name 7 = "seven"
  32. digit_to_name 8 = "eight"
  33. digit_to_name 9 = "nine"
  34. digit_to_name 10 = "ten"
  35. digit_to_name 11 = "eleven"
  36. digit_to_name 12 = "twelve"
  37. digit_to_name 13 = "thirteen"
  38. digit_to_name 14 = "fourteen"
  39. digit_to_name 15 = "fifteen"
  40. digit_to_name 16 = "sixteen"
  41. digit_to_name 17 = "seventeen"
  42. digit_to_name 18 = "eighteen"
  43. digit_to_name 19 = "nineteen"
  44. digit_to_name 20 = "twenty"
  45. digit_to_name 30 = "thirty"
  46. digit_to_name 40 = "forty"
  47. digit_to_name 50 = "fifty"
  48. digit_to_name 60 = "sixty"
  49. digit_to_name 70 = "seventy"
  50. digit_to_name 80 = "eighty"
  51. digit_to_name 90 = "ninety"
  52. digit_to_name 1000 = "one thousand"
  53. digit_to_name x
  54. | (mod x 100) == 0 = digit_to_name (div x 100) ++ " hundred"
  55. | x < 100 = digit_to_name (rd2nt x) ++ " " ++ digit_to_name (mod x 10)
  56. | x < 1000 = digit_to_name (div x 100) ++ " hundred and " ++ digit_to_name (mod x 100)
  57. isNotSpace :: Char -> Bool
  58. isNotSpace x = isSpace x |> not
  59. solution :: Int
  60. solution = map digit_to_name [1..1000] |> map (filter isNotSpace) |> map length |> sum
  61. main :: IO ()
  62. main = putStrLn ("Solution: " ++ show solution)