숫자를 영어로 읽기
영어에서 숫자는 110까지가 아닌 119까지가 별개의 이름으로 정해져 있다. 20~99까지는 10의 자리를 표현하는 단어와 1의 자리를 표현하는 단어를 결합하여 표시한다. (twenty one, forty five...)
100의 경우 1의 자리에 대한 단어 + hundred 로 쓰이며, 100 이하의 자리에 값이 있는 경우에는 and를 쓴다. 참고로 hundred는 항상 단수형으로만 쓰인다.
따라서 각 경우는 다음과 같다.
- 1000인 경우에는 "one thousand"이다.
- 100으로 나눈 몫 + "hundred", 100으로 나눈 몫이 없으면 생략
- 100으로 나눈 몫이 0보다 크고 나머지가 있는 경우 "and" 추가
- 100으로 나눈 나머지가 20 이상인 경우, 10으로 나눈 몫과 나머지에 해당하는 단어를 붙인다.
- 100으로 나눈 나머지가 19이하인 경우 지정된 단어
참고로 줄리아에서 문자열은 *
으로 결합한다.
# 정수를 받아서 이를 읽은 문자열을 리턴한다.
function readnum(n)
n > 1000 && error("Error") # 1000보다 큰 수는 에러
n == 1000 && return "onethousand" # 1000 일 때
s = ""
t = """one two three four five six seven eight nine ten eleven twelve
thirteen fourteen fifteen sixteen seventeen eighteen nineteen""" |> split
h = "twenty thirty forty fifty sixty seventy eighty ninety" |> split
q, r = divrem(n, 100)
# 100으로 나눈 몫이 있는 경우
q > 0 && (s *= h[q] * "hundred" * (r > 0 ? "and" : ""))
# 그 나머지가 20 이상인 경우
r >= 20 && (s *= t[r ÷ 10 - 1]; r %= 10)
# 19 이하의 값
r > 0 && (s *= h[r])
return s
end
@time 1:1000 .|> readnum .|> length |> sum |> println
사실 문제에서 요구하는 것은 글자의 수 이므로 readnum 함수는 문자열이 아니라 추가되는 단어의 길이만 계산하는 식으로 써도 된다.
function readnum2(n)
n > 1000 && return 0
n == 1000 && return 11
s = 0
t = [3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8]
h = [6, 6, 5, 5, 5, 7, 6, 6]
q, r = divrem(n, 100)
q > 0 && (s += h[q] + 7 + (r > 0 ? 3 : 0))
r >= 20 && (s += h[r ÷ 10 - 1]; r %= 10)
r > 0 && (s += t[r])
return s
end