1부터 5까지의 숫자를 영어로쓰면 one, two, three, four, five이고 각 단어의 길이를 더하면 3+3+5+4+4+=19이므로 사용된 글자는 모두 19개입니다. 1부터 1,000까지 영어로 썼을 때는 모두 몇 개의 글자를 사용해야 할까요? 빈칸이나 하이픈은 셈에서 제외하면 단어 사이에 and는 셈에 넣습니다. 예를 들어 342를 영어로 쓰면 three hundred and forty-two가 되어서 23글자, 115 = one hundred and fifteen의 경우에는 20글자가 됩니다.
접근
숫자를 영단어로 변환하는 함수를 작성하고, 1 ~ 1,000 의 범위에 대해 이 함수를 적용한 후, 글자 수를 모두 더하면 되겠다. 영어 단어를 숫자로 변환할 때의 규칙에 대해서 정리해보자.
- 1,000은 “one thounsand” 가 된다.
- 100 단위인 “hundred”는 200, 300을 표현할 때에는 -s를 붙이지 않는다. -s를 붙이는 경우는 “hundreds of ***” 처럼 쓸 때 뿐이다.
- 100 단위 아래로 10, 1 단위의 값이 남아있는 경우, 중간에 “and”를 사용한다.
- 21, 32를 각각 “twenty one”, “thirty two”라고 표현하는 것과 달리, 1 ~ 19 까지는 하나의 개별적인 단어로 표시한다. 따라서 20이상인 수는 10으로 나눈 몫과 나머지에 따라서 10단위 단어와 1단위 단어를 결합하고, 19 이하의 수는 해당 단어만 사용하면 된다.
아래 read_number()
함수는 위 규칙을 적용하여 1,000 이하의 숫자를 영단어로 변환해준다.
def read_number(n: int) -> str:
# 1000인 경우
if n == 1000:
return "onethousand"
res = []
ws1 = (". one two three four five six seven eight nine ten eleven twelve thirteen "
"fourteen fifteen sixteen seventeen eighteen nineteen").split()
ws2 = (". . twenty thirty forty fifty sixty seventy eighty ninety").split()
# 100 단위
h, n = divmod(n, 100)
if h > 0:
res.extend([ws1[h], "hundred", "and" if n > 0 else ""])
# 10단위, 1단위
if n > 19:
t, n = divmod(n, 10)
res.extend([ws2[t], ws1[n] if n > 0 else ""])
else:
res.append(ws1[n] if n > 0 else "")
return ''.join(res)
print(read_number(239))
# "twohundredandthirtynine"
위 함수를 사용하여 1 ~ 1000 사이에 적용한 후, 글자수로 변환하고 합산하면 된다.
print(sum(len(read_number(i + 1)) for i in range(1000)))