Odległość do czterech

13

To wyzwanie jest oparte na tym filmie . Zalecam obejrzenie go przed wypróbowaniem tego wyzwania.

Najpierw definiujemy funkcję. Ta funkcja ( OEIS ) przyjmuje na wejściu liczbę całkowitą n i wyświetla liczbę liter w angielskiej reprezentacji n (bez spacji i łączników). Na przykład „trzy” ma 5 liter, więc 3 odwzorowuje na 5.

Jak pokazano na filmie rozpoczynającym się od dowolnej liczby powtarzającej się, ten proces ostatecznie doprowadzi do liczby 4, która będzie mapować się na zawsze.

Oto przybliżony skierowany wykres pokazujący orbity liczb mniejsze niż 16:

  12 11
    \|      
15 2 6 1 10 14 13
  \ \|/ /  /  /
   7 3-/  8--/
    \|   /
 9 0 5--/
  \ \|
   \-4

Wyzwanie polega na określeniu liczby kroków, które wykona liczba (lub ile razy ta funkcja musi zostać zastosowana do liczby) przed osiągnięciem czterech (tj. Poziom na pokazanym wykresie skierowanym).

Formowanie liczb angielskich

Oto krótkie wyjaśnienie, w jaki sposób należy sformułować angielskie słowa dla tego wyzwania:

Numery od jeden do dziewiętnaście to:

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

W przypadku liczb większych niż dziewiętnaście proces wygląda następująco:

Jeśli liczba ma setki miejsc, zacznij od nazwy cyfry w setkach miejsc i „sto”.

na przykład

100 -> "onehundred"

Jeśli reszta jest mniejsza niż dwadzieścia, dołącz reprezentację w języku angielskim.

na przykład

714 -> "sevenhundredfourteen"

W przeciwnym razie, jeśli cyfra dziesiątek nie jest zerowa, dołącz odpowiednią reprezentację:

2-> twenty
3-> thirty
4-> forty
5-> fifty
6-> sixty
7-> seventy
8-> eighty
9-> ninety

na przykład

470 -> "fourhundredseventy"

Wreszcie, jeśli jest jedna cyfra, dołącz jej reprezentację

na przykład

681 -> "sixhundredeightyone"

Dalsze postanowienia

  • W przypadku liczb większych niż sto należy pominąć znaki „i” podczas liczenia liczby liter. Na przykład 577 to „pięćset siedemdziesiąt siedem”, które ma 23 litery.

  • Twój program musi akceptować wszystkie liczby całkowite większe niż 0 i mniejsze niż 1000 jako dane wejściowe standardowymi metodami.

  • Twój program musi wypisać liczbę kroków wymaganych do standardowych metod wyjścia.

  • To jest codegolf, więc wygrywa rozwiązanie z najmniejszą liczbą bajtów.

Przypadki testowe

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 
Ad Hoc Garf Hunter
źródło
1
Powiązane Myślałem, że to był dupek, ale nie mogę go znaleźć.
James
Co się stało z „i”? A raczej, dlaczego pomijać i ?!
Jonathan Allan,
@JonathanAllan cuz '
Murica

Odpowiedzi:

5

JavaScript (ES6), 106 bajtów

f=(n,a="03354435543668877998")=>n-4&&1+f(7*(n>99)-(-a[n/100|0]-(a[n%=100]||a[n%10])-"0066555766"[n/10|0]))

Ciągi wydają się być najlepszym sposobem na zakodowanie długości, pomimo narzutu konwersji numerycznej.

Neil
źródło
Rany, prawie tak wyglądała moja (prawie opublikowana) odpowiedź, tylko 11 bajtów krótsza.
ETHprodukcje
@ETHproductions Dobrze, że grałem w golfa 16 bajtów przed opublikowaniem go!
Neil,
2

Python, z num2words, 97 113 115 94 93 92 bajtów

+16 bajtów (zapomniałem dzielenia że num2words stosuje który nie zmienia wyników żadnego z przypadków testowych, choć 23i 577każdy ma myślnika)
+2 bajtów (zapomniałem to f=chociaż rekurencyjna)
-20 bajtów (wykorzystania re)
-8 bajty dzięki @Wheat Wizard (użytkowania ~, należy wymienić n!=4z n-4i ... jeden import linia> _ <)
-1 bajt dzięki @Cyoce (przestrzeń z 4 and)

import re,num2words as w
f=lambda n:n-4and-~f(len(re.sub('\W|and','',w.num2words(n))))

Liczy tylko liczbę kroków; działa również na duże i ujemne liczby całkowite ( \Wznajduje spacje, przecinki i łączniki w wyniku funkcji num2words):

>>> for test in (1,4,7,23,577,600,-1*2**96,3**96):
...     print('test: {0}  ->  {1}'.format(test, f(test)))
...
test: 1  ->  3
test: 4  ->  0
test: 7  ->  2
test: 23  ->  5
test: 577  ->  6
test: 600  ->  4
test: -79228162514264337593543950336  ->  4
test: 6362685441135942358474828762538534230890216321  ->  5

Oto ostatni przypadek, krok po kroku:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five
Jonathan Allan
źródło
1
Nie potrzebujesz f=wcześniejszej funkcji lambda
Ad Hoc Garf Hunter,
1
Spróbuj import re,num2words as rzamiast dwóch różnych instrukcji.
Ad Hoc Garf Hunter,
1
n-4to to samo, con!=4
Ad Hoc Garf Hunter
1
@WheatWizard num2wordsjest w, rejest nadal re- zwróć uwagę, że zarówno moduł, jak i funkcja są nazywanenum2words
Jonathan Allan
1
Ok ostatni, and 1+można go zastąpić, and-~aby zaoszczędzić jeden bajt
Ad Hoc Garf Hunter
1

Pyth - 54 bajty

Spróbuje refaktoryzować.

KjC"Y©åláóê¤"Ttl.u?<NyT@KNs+V@LKJ_jNT[Z@jC"Ckg"ThtJ7

Pakiet testowy .

Maltysen
źródło
1

Mathematica, 89 bajtów

Length@FixedPointList[StringLength@StringReplace[IntegerName@#,{" "->"","-"->""}]&,#]-2&

Typowa matematyka: dobre wbudowane funkcje, złe długie nazwy funkcji. FixedPointListstosuje swój pierwszy argument (funkcję) wielokrotnie do drugiego argumentu, dopóki odpowiedź się nie zmieni, wyświetlając wszystkie wyniki; wyniki obejmują oryginalne dane wejściowe i dwie kopie powtarzanych danych wyjściowych, stąd -2na końcu. Wbudowane oprogramowanie Mathematica IntegerNamezawiera spacje i łączniki, więc musimy się ich pozbyć ręcznie.

Irytujące IntegerNamewyjście zawiera znak „-” (Unicode # 8208) zamiast zwykłych łączników; dlatego przesyłanie to 89 bajtów zamiast 88. (I nie mogłem poprzedzić powyższego kodu czterema spacjami i pozwolić, aby zaakceptował znak Unicode - jakakolwiek pomoc? - więc powyższy kod nie będzie działał poprawnie, jeśli zostanie wycięty i wklejony .)

Greg Martin
źródło
1

Python 2.7, 344 216 208 bajtów:

x=`input()`;c=0;y=lambda v:dict(zip(range(0,10),[0]+v));l=[3,3,5,4,4,3,5,5,4];d=y(l);e=y([3,6,6,6,5,5,7,7,6]);f=y([i+7for i in l])
while x!='4':x=`sum([q[int(r)]for q,r in zip([d,e,f],x[::-1])])`;c+=1
print c

Nie używa żadnych bibliotek zewnętrznych w przeciwieństwie do innych odpowiedzi w języku Python. Przenosi dane wejściowe stdini wyjściowe do stdout.

Zamień na wszystkie przypadki testowe!

Wyjaśnienie

Najpierw tworzy 3 słowniki, w których każda paruje długość reprezentacji angielskich słów dla każdej liczby z liczbą, którą reprezentuje w zamkniętym przedziale, odpowiednio [1,9]w miejscach jedynki, dziesiątki i setki. Na przykład, pierwsza pozycja w słowniku djest 1:3jak 1jest napisane onew języku angielskim i ma 3litery.

Następnie każda cyfra umieszczona w danych wejściowych ciągu xjest przypisywana do odpowiedniego słownika, po czym każda liczba w każdym miejscu jest dopasowywana do jej wartości w odpowiednim słowniku. Załóżmy na przykład, że wprowadzony numer to 23. Miejsce 20w dziesiątkach byłoby sparowane ze słownikiem e, w którym jest on dopasowany 6, a miejsce 3w jedności byłoby sparowane ze słownikiem d, w którym jest dopasowany 5. Te dopasowane cyfry są następnie dodawane razem, aby reprezentować długość angielskiej reprezentacji liczby, która jest przypisana xjako ciąg i tak długo, jak długo x!='4'trwa pętla while, zwiększając co1za każdym razem, aby przedstawić liczbę dotychczasowych kroków. Dlatego 23odpowiadałby 11, co z kolei odpowiadałoby, do 6którego zwróciłoby się, 3a następnie do, 5a na końcu 4, w wyniku 5całkowitej liczby kroków.

Wreszcie, gdy pętla się zakończy, wysyłana cjest wartość wyjściowa stdoutreprezentująca „Odległość do czterech”, która w tym przypadku byłaby 5.

R. Kap
źródło
1

Jawa, 556 295 bajtów

Dzięki @KevinCruijssen za oszczędność 261 bajtów

  void int(n) {int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;while(n>0){if(n/100>0)c+=(s[n/100]+7);else {if(n>0&n<25){c+=s[n];break;}else{c+=s[(n/10)+22];}}n=n%t;t=t/10;}while(c!=4){v++;c=s[c];}System.out.print(v);}


Nie golfowany:

  void int(n) {

    int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};
     int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;
         while(n>0){
            if(n/100>0)
                c+=(s[n/100]+7);
            else {if(n>0&n<25){
                c+=s[n];
            break;
            }
            else{
                c+=s[(n/10)+22];

            }
            }
            n=n%t;
            t=t/10;
        }

        while(c!=4)
        {
            v++;
        c=s[c];
        }
System.out.print(v);
}
Numberknot
źródło
s++
Wydaje
@KevinCruijssen Deklaruję S (licznik) jako INT i STRING też .... java automatycznie decyduje, że jest to INT.
Numberknot
Cóż, jeśli uruchomię twój kod w ideone lub mój Eclipse IDE, to się nie powiedzie, ponieważ masz dwa s.. Btw, możesz zagrać w golfa o całkiem sporą kwotę w następujący sposób:int c(int n){int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8,6,9,9,11,10,6,5,5,5,7,6,6},c=0,t=(int)Math.pow(10,(int)Math.log10(n)),x=1;while(n>0)if(n/100>0)c+=s[n/100]+7;else{if(n>0&n<25){c+=s[n];break;}else c+=s[(n/10)+22];}n%=t;t/=10;}for(;c!=4;x++,c=s[c]);return x;}
Kevin Cruijssen
Jestem zszokowany ...... co się stało z moim kodem i dzięki @ KevinCruijssen..i poprawiam to ... Jeszcze raz dziękuję.
Numberknot 12.09.16
Np :) Wydaje mi się, że można w jakiś sposób zagrać w golfa bez użycia if-else i włamać się tam (ale zostawię to komuś innemu), ale twój początkowy kod był świetną bazą do podjęcia wyzwania, więc +1 ode mnie.
Kevin Cruijssen