Distanza da quattro


13

Questa sfida si basa su questo video . Ti consiglio di guardarlo prima di provare questa sfida.

Per prima cosa definiamo una funzione. Questa funzione ( OEIS ) accetta un numero intero n come input e genera il numero di lettere nella rappresentazione inglese di n (senza spazi o trattini). Ad esempio "tre" ha 5 lettere, quindi 3 mappe a 5.

Come dimostrato nel video che inizia con qualsiasi numero che si ripete, questo processo alla fine si tradurrà in un quattro, che verrà mappato su se stesso per sempre.

Ecco un grafico diretto grezzo che mostra le orbite dei numeri inferiori a 16:

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

La tua sfida consiste nel determinare il numero di passaggi che un numero eseguirà (o il numero di volte in cui questa funzione deve essere applicata a un numero) prima di raggiungere quattro (ovvero il livello sul grafico diretto rappresentato).

Formare numeri inglesi

Ecco una breve spiegazione di come si dovrebbero formare parole inglesi per questa sfida:

I numeri da uno a diciannove sono:

uno, due, tre, quattro, cinque, sei, sette, otto, nove, dieci, undici, dodici, tredici, quattordici, quindici, sedici, diciassette, diciotto, diciannove

Per numeri maggiori di diciannove il processo è il seguente:

Se il numero ha un posto di centinaia, inizia con il nome della cifra nel posto di centinaia e "cento".

per esempio

100 -> "onehundred"

Se il resto è inferiore a venti, aggiungi la rappresentazione inglese del resto.

per esempio

714 -> "sevenhundredfourteen"

Altrimenti se la cifra delle decine non è zero aggiungere la rappresentazione corretta:

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

per esempio

470 -> "fourhundredseventy"

Infine, se c'è una cifra, aggiungi la sua rappresentazione

per esempio

681 -> "sixhundredeightyone"

Ulteriori Stipulazioni

  • Per numeri superiori a cento, dovresti tralasciare "e" quando contate il numero di lettere. Ad esempio 577 è "cinquecentosettantasette" che ha 23 lettere.

  • Il tuo programma deve accettare tutti i numeri interi maggiori di 0 e inferiori a 1.000 come input tramite metodi standard.

  • Il programma deve generare il numero di passaggi richiesti per i metodi di output standard.

  • Questo è codegolf, quindi vince la soluzione con il minor numero di byte.

Casi test

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 

1
Correlati Pensavo fosse un inganno, ma non riesco a trovarlo.
James,

Che cosa è successo a "e"? O meglio, perché lasciar perdere e ?!
Jonathan Allan,

@JonathanAllan cuz 'Murica
LegionMammal978

Risposte:


5

JavaScript (ES6), 106 byte

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

Le stringhe sembrano essere il modo migliore per codificare la lunghezza, nonostante l'overhead della conversione numerica.


Accidenti, è quasi esattamente quello che sembrava la mia (quasi postata) risposta, solo 11 byte in meno.
ETHproductions

@ETHproductions Meno male che mi sono sbarazzato di 16 byte prima di pubblicarlo!
Neil,

2

Python, con num2words, 97113 115 94 93 92 byte

+16 byte (dimenticato la sillabazione che num2words applica che non modifica i risultati di qualsiasi dei casi di test, anche se 23e 577hanno ciascuno un trattino)
+2 byte (dimenticato di includere f=anche ricorsiva)
-20 byte (uso re)
-8 byte grazie alla procedura guidata @Wheat (utilizzare ~, sostituire n!=4con n-4e ... importazione di una riga> _ <)
-1 byte grazie a @Cyoce (spazio da 4 and)

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

Conta solo il numero di passaggi; funziona anche con numeri interi grandi e negativi ( \Wtrova gli spazi, le virgole e i trattini nel risultato 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

Ecco l'ultimo caso, passo dopo passo:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five

1
Non hai bisogno di un f=prima della tua funzione lambda
Post Rock Garf Hunter,

1
Prova import re,num2words as rinvece delle due diverse dichiarazioni.
Post Rock Garf Hunter,

1
n-4è la stessa cosa din!=4
Post Rock Garf Hunter

1
@WheatWizard num2wordsè w, reè ancora re- si noti che sia il modulo che la funzione sono chiamatinum2words
Jonathan Allan

1
Ok, l'ultimo, and 1+può essere sostituito con and-~per salvare un byte
Post Rock Garf Hunter

1

Pyth - 54 byte

Proverà a refactoring.

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

Test Suite .


1

Mathematica, 89 byte

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

Mathematica tipica: buone funzioni integrate, nomi lunghi delle funzioni cattivi. FixedPointListapplica ripetutamente il suo primo argomento (una funzione) al secondo argomento fino a quando la risposta non cambia, elencando tutti i risultati; i risultati includono l'input originale e due copie dell'output ripetuto, quindi il-2 alla fine. L'incasso di Mathematica IntegerNamecontiene spazi e trattini, quindi dobbiamo liberarcene a mano.

IntegerNameL'output fastidioso contiene il carattere "-" (Unicode # 8208) anziché i trattini normali; ecco perché questo invio è di 89 byte anziché 88. (E non potrei precedere il codice sopra con quattro spazi e farlo accettare il carattere Unicode - qualche aiuto? - Quindi il codice sopra non funzionerà esattamente se tagliato e incollato .)


1

Python 2.7, 344 216 208 byte:

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

Non utilizza librerie esterne a differenza di altre risposte Python. Accetta input stdine output su stdout.

Repl.it con tutti i casi di test!

Spiegazione

In primo luogo crea 3 dizionari con ognuno accoppiando la lunghezza delle rappresentazioni delle parole inglesi di ciascun numero al numero che rappresenta nell'intervallo chiuso rispettivamente [1,9]in uno, decine e centinaia. Ad esempio, la prima voce nel dizionario dè 1:3come 1si scriveone in inglese e ha 3lettere.

Quindi, ciascuna cifra posizionata in un input di stringa xviene assegnata al dizionario corrispondente, dopodiché ogni numero in ogni posizione viene associato al suo valore nel dizionario corrispondente. Ad esempio, supponiamo che il numero di input fosse 23. Il posto 20in decine verrebbe abbinato al dizionario e, in cui è associato 6, e il posto in decine verrebbe 3associato al dizionario d, in cui viene associato 5. Queste cifre corrispondenti vengono quindi sommate per rappresentare la lunghezza della rappresentazione inglese del numero, che viene assegnato xcome stringa e, purché x!='4', il ciclo while continui, incrementando cdi1ogni volta per rappresentare il numero di passi compiuti finora. Pertanto, 23corrisponderebbe a passaggi totali.11, che a sua volta corrisponderebbe a 6cui si trasformerebbe 3e quindi a, 5e infine a 4, risultante5

Alla fine, una volta terminato il ciclo, cviene emesso per stdoutrappresentare la "Distanza da quattro", che in questo caso sarebbe 5.


1

Giava, 556 295 byte

Grazie a @KevinCruijssen per aver salvato 261 byte

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


Ungolfed:

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

Penso che tu abbia un errore nel tuo codice, perché s++non è possibile su un array di stringhe ..: S
Kevin Cruijssen,

@KevinCruijssen Dichiaro anche S (counter) come INT e STRING .... java decide automaticamente che è un INT.
Numberknot,

Bene, se eseguo il tuo codice in ideone o il mio IDE Eclipse fallisce perché ne hai due s.. A proposito, puoi giocare a golf il tuo codice con una quantità abbastanza grande come questa: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,

Sono scioccato ...... cosa succede al mio codice e grazie @ KevinCruijssen..e lo sto correggendo ... Grazie ancora.
Numberknot,

Np :) Penso che potrebbe essere giocato a golf un po 'di più in qualche modo senza usare l'if-if e irrompere lì (ma lo lascerò a qualcun altro), ma il tuo codice iniziale è stato un'ottima base per affrontare la sfida, quindi +1 da me.
Kevin Cruijssen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.