Quantas letras nesta palavra?

12

Inspirado no Projeto Euler # 17 , este é o seu desafio. Escreva um programa ou função completa que use um número como entrada e imprima ou retorne quantas letras seriam necessárias para contar até e incluindo esse número em inglês (começando em um). Você não inclui espaços, vírgulas ou hífens, mas deve incluir a palavra and. Por exemplo. 342 está escrito: Three Hundred and Forty-Two. São 23 letras.

Sua entrada será um número inteiro positivo. Você não precisa lidar com entradas inválidas. Built-ins ou bibliotecas que convertem números em inglês não são permitidos.

Aqui estão todas as regras de como escrever números. (Observação: percebo que algumas pessoas usam um conjunto diferente de regras para escrever números. Essas serão apenas as regras oficiais para o objetivo deste desafio)

1 a 20

um, dois, três, quatro, cinco, seis, sete, oito, nove, dez, onze, doze, treze, quatorze, quinze, dezesseis, dezessete, dezoito, dezenove, vinte

21 a 99

Junte-se a estes:

Vinte, trinta, quarenta, cinquenta, sessenta, setenta, oitenta, noventa

para estes:

-um, dois, três, quatro, cinco e cinco, seis, sete, oito e nove,

Note que quatro tem u, mas quarenta não!

Exemplos:

53: Fifty-three
60: sixty
72: seventy-two
99: ninety-nine

100 a 999

Escreva quantas centenas (cem, duzentos, trezentos etc.), um " e " e o restante do número, como acima. O e conta para a pontuação da sua letra.

Exemplos:

101: One hundred and one
116: One hundred and sixteen
144: One hundred and forty-four
212: Two hundred and twelve
621: Six Hundred and twenty-one

1.000 a 999.999

Escreva quantos milhares (mil, dois mil etc.), uma vírgula e o restante do número, como acima. Observe que, se você não tiver centenas, ainda precisará do e .

Exemplos:

1,101: One thousand, one hundred and one
15,016: Fifteen thousand and sixteen
362,928: Three hundred and sixty-two thousand, nine hundred and twenty-eight

Milhões

Escreva quantos milhões e o restante do número acima. Observe que "Um milhão" é 6 zeros "1.000.000".

Exemplos:

191,232,891: One hundred and ninety-one million, two hundred and thirty-two thousand, eight hundred and ninety-one
1,006,101: One million, six thousand, one hundred and one

A mesma regra se aplica a bilhões, trilhões, quadrilhões e acima, mas para o objetivo deste desafio, você não precisa lidar com números acima de 999.999.999 (novecentos e noventa e nove milhões, novecentos e noventa e nove mil, novecentos e noventa e nove.)

Solucionador de Python

Aqui está um pequeno script python para verificar as respostas:

import en 

def get_letter_num(s):
    count = 0
    for c in s:
        if c.isalpha():
            count += 1
    return count

number = input()
count = 0
for i in xrange(1, number + 1):
    count += get_letter_num(en.number.spoken(i))

print count

Observe que isso utiliza a biblioteca de linguística NodeBox para converter números em inglês. (sim, acabei de quebrar minha própria regra, mas essa não é uma resposta competitiva) Isso está disponível gratuitamente aqui .

E / S de amostra

7: 27
19: 106
72: 583
108: 1000
1337: 31,131
1234567: 63,448,174
James
fonte
1
Por que é cento e um , mas depois um milhão, seis mil, cento e um sem o e ?
Geobits
1
@FryAmTheEggman Usando seu script python, 1100 -> mil e cem; 1200 -> mil e duzentos, 1000100 -> um milhão e cem, 1000200 -> um milhão e duzentos. Eu acho que qualquer A) DJ McGoathem deve abordar os 1100 e 1000100 casos especiais na sua pergunta, ou B) corrigir seus casos de teste
TheNumberOne
4
Por que o "e"? Os nomes próprios para os números nunca o usam: 123 = "cento e vinte e três"
ricdesi
1
@ricdesi Eu concordo. Relacionado . As pessoas contam "mil um, mil e dois, ...", sem os e s.
mbomb007

Respostas:

1

Python 2, 266 259 236 229 228 bytes

Isso funciona para todas as entradas abaixo de um bilhão. Isso funciona para todos os casos de teste.

def l(n):b=[6,3,2][(n<1000)+(n<10**6)];c=10**b;return int("0335443554"[n%10])+int("0366555766"[n/10])+(n-10in[4,6,7,9])if n<100else l(n/c)+(l(n%c)or-3*(b<3))+7+(b<6)+2*(b<3)+3*(b>2)*(0<n%c<101)
print sum(map(l,range(input()+1)))

Para modificá-lo para caber na pergunta conforme indicado (por exemplo, não trate números que terminem com 100 especiais), substitua o número 101 no final da primeira linha por 100.

Explicação:

def l(n):
    b=[6, 3, 2][(n < 1000) + (n < 10**6)] # b = 2 if n < 1000 else 3 if n < 1000000 else 6
    c=10**b
    return (                            # Parenthesis added for readability.
            int("0335443554"[n % 10]) + # Compute length of last digit. one -> 3, seven -> 5, etc.
            int("0366555766"[n / 10]) + # Compute length of second to last digit. ten -> 3, eighty -> 6, etc.
            (n - 10 in[4, 6, 7, 9])     # Add one to length if the number is 14, 16, 17, or 19.

            if n < 100 else             # Use above procedure if the number is under 100.
                                        # If otherwise, use below procedure.

            l(n / c) +                  # Compute length of the top portion of number.
                (l(n % c) or            # Compute length of bottom portion of number.
                -3 * (b < 3)) +         # If the number < 1000 and is a multiple of 100,
                                        # subtract 3 from the length because of missing and.
            7 +                         # Add 7 to the length for "million"
            (b < 6) +                   # Add 8 to the length for "thousand"
            2 * (b < 3) +               # Add 10 to the length for "hundred and"
                3 *                     # Add 3 to the length for another "and"
                (b > 2) *               # if the number >= 1000
                (0 < n % c < 101)       # and the bottom portion > 0 and <= 100
    )
print sum(map(l,range(input()+1)))      # For the reader to figure out.
O número um
fonte