Ile liter w tym słowie?

12

Zainspirowany projektem Euler # 17 , to twoje wyzwanie. Napisz pełny program lub funkcję, która przyjmuje liczbę jako dane wejściowe, a następnie wydrukuj lub zwróć liczbę liter potrzebnych do policzenia tej liczby w języku angielskim (od jednej). Nie podajesz spacji, przecinków ani łączników, ale powinieneś dołączyć słowo and. Na przykład. 342 jest opisana: Three Hundred and Forty-Two. Ma 23 litery.

Twój wkład będzie dodatnią liczbą całkowitą. Nie musisz obsługiwać nieprawidłowych danych wejściowych. Wbudowane biblioteki lub biblioteki konwertujące liczby na angielski są niedozwolone.

Oto wszystkie zasady pisowni liczb. (Uwaga: zdaję sobie sprawę, że niektóre osoby stosują inny zestaw zasad do literowania liczb. To będą oficjalne zasady do celów tego wyzwania)

Od 1 do 20

jeden, dwa, trzy, cztery, pięć, sześć, siedem, osiem, dziewięć, dziesięć, jedenaście, dwanaście, trzynaście, czternaście, piętnaście, szesnaście, siedemnaście, osiemnaście, dziewiętnaście, dwadzieścia

21 do 99

Dołącz do tych:

Dwadzieścia, trzydzieści, czterdzieści, pięćdziesiąt, sześćdziesiąt, siedemdziesiąt, osiemdziesiąt, dziewięćdziesiąt

do tych:

-jeden, -dwóch, -trzy, -four, -five, -six, -seven, -eight, -nine,

Zauważ, że cztery mają u, ale czterdzieści nie!

Przykłady:

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

Od 100 do 999

Napisz, ile setek (sto, dwieście, trzysta itd.), „ I ”, a resztę liczby jak wyżej. Liczby i liczą się do wyniku twojego listu.

Przykłady:

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

Od 1000 do 999,999

Napisz, ile tysięcy (tysiąc, dwa tysiące itd.), Przecinek, a następnie resztę liczby jak wyżej. Pamiętaj, że jeśli nie masz setek, nadal potrzebujesz i .

Przykłady:

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

Miliony

Napisz, ile milionów, a następnie resztę liczby jak wyżej. Zauważ, że „milion” to 6 zer „1 000 000”.

Przykłady:

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

Ta sama zasada dotyczy miliardów, trylionów, biliardów i więcej, ale na potrzeby tego wyzwania nie musisz obsłużyć żadnej liczby powyżej 999,999,999 (dziewięćset dziewięćdziesiąt dziewięć milionów, dziewięćset dziewięćdziesiąt dziewięć tysięcy, dziewięćset dziewięćdziesiąt dziewięć.)

Solver Python

Oto krótki skrypt Pythona do weryfikacji odpowiedzi:

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

Zauważ, że używa to biblioteki językowej NodeBox do konwersji liczb na angielski. (tak, właśnie złamałem własne reguły, ale nie jest to konkurencyjne odpowiedź) To jest swobodnie dostępny tutaj .

Próbki we / wy

7: 27
19: 106
72: 583
108: 1000
1337: 31,131
1234567: 63,448,174
James
źródło
1
Dlaczego jest sto jeden , a potem jeden milion sześć tysięcy sto jeden bez i ?
Geobits
1
@FryAmTheEggman Używając swojego skryptu python, 1100 -> tysiąc sto; 1200 -> tysiąc dwieście, 1000100 -> jeden milion sto, 1000200 -> jeden milion dwieście. Myślę, że albo A) DJ McGoathem powinien zająć się specjalnymi przypadkami 1100 i 1000100 w swoim pytaniu, lub B) poprawić swoje przypadki testowe
TheNumberOne
4
Dlaczego „i”? Właściwe nazwy dla liczb nigdy go nie używają: 123 = „sto dwadzieścia trzy”
ricdesi
1
@ricdesi Zgadzam się. Związane . Ludzie liczą „tysiąc jeden, tysiąc dwa, ...”, bez and .
mbomb007

Odpowiedzi:

1

Python 2, 266 259 236 229 228 bajtów

Działa to dla wszystkich danych wejściowych poniżej miliarda. Działa to dla wszystkich przypadków testowych.

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)))

Aby zmodyfikować go, tak aby pasował do pytania, jak podano (np. Nie traktuj liczb kończących się na 100 specjalnych), po prostu zamień liczbę 101 na końcu pierwszego wiersza na 100.

Wyjaśnienie:

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.
Numer jeden
źródło