Code Golf: Four è magico


88

Il puzzle

Un piccolo puzzle che ho sentito mentre ero al liceo è andato qualcosa del genere ...

  • L'interrogante mi chiederebbe di dargli un numero;
  • Nel sentire il numero, l'interrogante lo farebbe ripetutamente (ad esempio, potrebbe dire che dieci è tre ) fino ad arrivare al numero 4 (a quel punto finirebbe con quattro è magico ).
  • Qualsiasi numero sembra essere trasformabile in quattro alla fine, non importa quale.

L'obiettivo era cercare di capire la funzione di trasformazione e quindi essere in grado di sorvegliare in modo affidabile questo puzzle da soli.

La soluzione

La funzione di trasformazione in ogni fase era quella di

  • Prendi il numero in questione,
  • Contare il numero di lettere nella rappresentazione della parola inglese, ignorando un trattino o spazi o "e" (ad es. "Dieci" contiene 3 lettere, "trentaquattro" contiene 10 lettere, "centoquarantatre" contiene 20 lettere).
  • Restituisci quel numero di lettere.

Per tutti i numeri che ho sempre voluto testare, questo converge a 4. Poiché "quattro" contiene anche quattro lettere, qui ci sarebbe un ciclo infinito; invece è semplicemente indicato come magia per convenzione per terminare la sequenza.

La sfida

La tua sfida è creare un pezzo di codice che leggerà un numero dall'utente e quindi stampare le righe che mostrano la funzione di trasformazione applicata ripetutamente fino a quando non viene raggiunto "quattro è magico".

Nello specifico:

  1. Le soluzioni devono essere programmi completi in sé e per sé. Non possono essere semplicemente funzioni che prendono un fattore numero nell'input.
  2. L'input deve essere letto dallo standard input. (Il piping da "echo" o l'utilizzo del reindirizzamento dell'input va bene poiché anche questo va da stdin)
  3. L'input dovrebbe essere in formato numerico.
  4. Per ogni applicazione della funzione di trasformazione, dovrebbe essere stampata una riga:, a is b.dove aeb sono forme numeriche dei numeri nella trasformazione.
  5. I punti fermi (periodi) SONO obbligatori!
  6. L'ultima riga dovrebbe naturalmente dire 4 is magic..
  7. Il codice dovrebbe produrre un output corretto per tutti i numeri da 0 a 99 .

Esempi:

> 4
4 is magic.

> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.

> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.

> 0
0 is 4.
4 is magic.

> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

Il vincitore è la presentazione più breve in base al numero di caratteri del codice sorgente, che è anche corretto .

BONUS

Puoi anche provare a scrivere una versione del codice che stampa i NOMI INGLESI per i numeri con ciascuna applicazione della funzione di trasformazione. L'input originale è ancora numerico, ma le righe di output dovrebbero avere la forma della parola del numero.

(Doppio bonus per disegnare forme con il tuo codice)

(EDIT) Alcuni chiarimenti:

  1. Voglio che la parola appaia su entrambi i lati in tutti i casi applicabili, ad es Nine is four. Four is magic.
  2. Non mi interessa l'uso delle maiuscole, però. E non mi interessa come separare le parole token, anche se dovrebbero essere separate: ninety-nineva bene, ninety nineva bene, ninetyninenon va bene.

Considero questi una categoria separata per la competizione bonus per quanto riguarda la sfida, quindi se scegli questo, non preoccuparti che il tuo codice sia più lungo della versione numerica.

Sentiti libero di inviare una soluzione per ogni versione.


1
Quanto alto dovremmo gestire? <100? <1000? <1000000? <2 ** 31?
P Daddy

1
Dal momento che questo deve solo andare da 0 a 99, sospetto che una soluzione rapida e breve sarebbe quella di codificare i valori a cui mappare 0-99, quindi eseguire il ciclo fino a raggiungere 4. Dopodiché, inizia il microtweaking.
Beska

@P Daddy ... la parte 6 dice solo 0-99.
Beska


14
4 è solo magico perché è stato scelto da un giusto lancio di dadi.
VirtuosiMedia

Risposte:


57

GolfScript - 101 96 93 92 91 90 94 86 byte

90 → 94: Uscita fissa per multipli di 10
94 → 86.: Codice ristrutturato. Utilizzo della base 100 per rimuovere i caratteri non stampabili.
86 → 85: Cast più corto alla corda.

{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."

perché è così in basso? è più corto di quello lisp e non utilizza una funzione di formattazione incorporata
Claudiu

36
Mi piace come finisce il codice "magic.", lo riassume praticamente.
Aistina

@Aistina: è facile in questa sfida, credo. :-)
Platinum Azure

9
@Aistina: haha, è piuttosto divertente. "mumbo jumbo yada yada..magic"
vol7ron

1
@P Daddy The dviene estratto da )as 100e viene utilizzato come radice per la conversione di base.
Nabb

85

Perl, circa 147 caratteri

Liberamente basato sulla soluzione di Platinum Azure:

               chop
              ($_.=
              <>);@
             u="433
            5443554
           366  887
          798   866
         555    766
        "=~     /\d
       /gx      ;#4
      sub       r{4
     -$_        ?$_
    <20         ?$u
   [$_          ]:(
  $'?           $u[
 $']            :0)
+$u[18+$&]:magic}print"
$_ is ",$_=r(),'.'while
                /\d
                /x;
                444

1
@ Platinum Azure il modo in cui questo ottiene il suo input è attraverso l'uso di pop, senza argomenti. Al di fuori di una subroutine poprimuove e restituisce il cui ultimo valore @ARGVè l'elenco degli argomenti al programma Perl. Potrebbe essere facilmente sostituito con shift, ma questo aggiunge altri 2 caratteri. Vedi: p3rl.org/pop
Brad Gilbert

sembra che tu abbia bisogno di un carattere di nuova riga '.', che è 2 per \no 1 se stai contando gli spazi bianchi in '. '(lo spazio è il letterale di nuova riga)
vol7ron

Un po 'di più, ma la creatività fa molta strada nel mio libro.
Beska

@ Platinum Azure et al: sta ricevendo il suo input da stdin. Questo è il modo per farlo in Perl. (Forse l'ha cambiato dopo il tuo commento?)
Frank

@P Daddy: gemiti ma +1 al tuo commento comunque
Platinum Azure

30

Common Lisp 157 caratteri

Nuova versione più conforme, che ora legge l'input standard e ignora spazi e trattini:

(labels((g (x)(if(= x 4)(princ"4 is magic.")(let((n(length(remove-if(lambda(x)(find x" -"))(format nil"~r"x)))))(format t"~a is ~a.~%"x n)(g n)))))(g(read)))

In forma leggibile dall'uomo:

 (labels ((g (x)
           (if (= x 4)
            (princ "4 is magic.")
            (let ((n (length (remove-if (lambda(x) (find x " -"))
                                        (format nil "~r" x)))))
               (format t"~a is ~a.~%" x n)
               (g n)))))
    (g (read)))

E alcuni test vengono eseguiti:

>24
24 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

>23152436
23152436 is 64.
64 is 9.
9 is 4.
4 is magic.

E la versione bonus, a 165 caratteri:

 (labels((g(x)(if(= x 4)(princ"four is magic.")(let*((f(format nil"~r"x))(n(length(remove-if(lambda(x)(find x" -"))f))))(format t"~a is ~r.~%"f n)(g n)))))(g(read)))

Dando

>24
twenty-four is ten.
ten is three.
three is five.
five is four.
four is magic.

>234235
two hundred thirty-four thousand two hundred thirty-five is forty-eight.
forty-eight is ten.
ten is three.
three is five.
five is four.
four is magic.

5
Pensavo "ventiquattro" ha solo 10 lettere?
kennytm

1
Anche i numeri dopo "è" dovrebbero essere testo.
Mike DeSimone

5
perché è così in alto? altri non usano una funzione di formattazione incorporata e sono meno caratteri
Claudiu

3
@ Claudiu Perché Common Lisp è fantastico.
Mornedhel

3
Non importa quanti colpi fai se non porti la palla in buca. Le persone sembrano dimenticarlo quando votano a favore di soluzioni sbagliate.
Mark Peters

21

Python 2.x, 144 150 154 166 chars

Questo separa il numero in decine e unità e le somma. La proprietà indesiderabile dell'operatore pseudo-ternario a and b or cche cviene restituito se bè 0 viene abusata qui.

n=input()
x=0x4d2d0f47815890bd2
while n-4:p=n<20and x/10**n%10or 44378/4**(n/10-2)%4+x/10**(n%10)%10+4;print n,"is %d."%p;n=p
print"4 is magic."

La precedente versione ingenua (150 caratteri). Basta codificare tutte le lunghezze come un numero intero.

n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."

Scusa, volevo in particolare il punto fermo solo per cose come questa. Sorriso Buona entrata però! (EDIT: non conosco Python, ma potresti n,"is",p,"."? Penso che salverai ancora alcuni personaggi se sto contando bene)
Platinum Azure

2
@Plat: Ciò causerebbe uno spazio extra prima del file ..
kennytm

@ KennyTM: Oh, duh, avrei dovuto notarlo anche dallo snippet. Ops! Ebbene, comunque, come ho detto, alcune specifiche sono state progettate appositamente per complicare un po 'le cose. :-)
Platinum Azure

Possiamo accorciarlo usando una base più alta di 36?
MikeD

@ MikeD: No. Dalla documentazione di Python: "Il parametro base fornisce la base per la conversione (che è 10 per impostazione predefinita) e può essere qualsiasi numero intero compreso nell'intervallo [2, 36] o zero." Ora potresti essere in grado di utilizzare una funzione diversa da int(), dì qualcosa dai moduli structo base64...
Mike DeSimone

20

C - con parole numeriche

445 431 427 421 399 386 371 359 * 356 354 348 347 caratteri

Questo è tutto. Non credo di poterlo accorciare.

Tutte le nuove righe sono leggibili e possono essere rimosse:

i;P(x){char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,
fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,
4RmagicS,zero,";while(x--)if(*++p-44&&!x++)*p>95|*p<48?putchar(*p),++i:P(*p-48);
}main(c){for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))P(c?c>19?P(c/10+18),
(c%=10)&&putchar(45):0,c:37);P(36);}

Di seguito, è un po 'non minimizzato, ma ancora piuttosto difficile da leggere. Vedi sotto per una versione più leggibile.

i;
P(x){
    char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
    while(x--)
        if(*++p-44&&!x++)
            *p>95|*p<48?putchar(*p),++i:P(*p-48);
}
main(c){
    for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))
        P(c?
            c>19?
                P(c/10+18),
                (c%=10)&&
                    putchar(45)
            :0,
            c
        :37);
    P(36);
}

Espanso e commentato:

int count; /* type int is assumed in the minified version */

void print(int index){ /* the minified version assumes a return type of int, but it's ignored */
    /* see explanation of this string after code */
    char *word =
        /* 1 - 9 */
        ",one,two,three,four,five,six,sM,eight,nine,"
        /* 10 - 19 */
        "tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,"
        /* 20 - 90, by tens */
        "twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,"
        /* lookup table */
        "en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";

    while(index >= 0){
        if(*word == ',')
            index--;
        else if(index == 0) /* we found the right word */
            if(*word >= '0' && *word < 'a') /* a compression marker */
                print(*word - '0'/*convert to a number*/);
            else{
                putchar(*word); /* write the letter to the output */
                ++count;
            }
        ++word;
    }
}
int main(int argc, char **argv){ /* see note about this after code */
    scanf("%d", &argc); /* parse user input to an integer */

    while(argc != 4){
        count = 0;
        if(argc == 0)
            print(37/*index of "zero"*/);
        else{
            if(argc > 19){
                print(argc / 10/*high digit*/ + 20/*offset of "twenty"*/ - 2/*20 / 10*/);
                argc %= 10; /* get low digit */

                if(argc != 0) /* we need a hyphen before the low digit */
                    putchar('-');
            }
            print(argc/* if 0, then nothing is printed or counted */);
        }
        argc = count;
        print(34/*" is "*/);
        print(argc); /* print count as word */
        print(35/*".\n"*/);
    }
    print(36/*"four is magic.\n"*/);
}

Informazioni sulla stringa codificata vicino all'inizio

I nomi dei numeri vengono compressi utilizzando uno schema molto semplice. Le sottostringhe utilizzate di frequente vengono sostituite con indici di un carattere nella matrice dei nomi. Una "tabella di ricerca" di voci di nomi extra viene aggiunta alla fine per le sottostringhe non utilizzate nella loro interezza nel primo set. Le ricerche sono ricorsive: le voci possono fare riferimento ad altre voci.

Ad esempio, il nome compresso per 11 è elM. La print()funzione restituisce i caratteri ee l('L' minuscola, non il numero '1') testualmente, ma poi trova il M, quindi si chiama con l'indice della 29a voce (ASCII 'M' - ASCII '0') nella tabella di ricerca. Questa stringa è evL, quindi restituisce ee v, quindi chiama di nuovo se stessa con l'indice della 28a voce nella tabella di ricerca, che è en, e viene restituita alla lettera. Questo è utile perché enè utilizzato anche in eLper la een(usato dopo eighta eighteen), che viene utilizzato in tOper teen(usato per ogni altro -teennome).

Questo schema si traduce in una compressione abbastanza significativa dei nomi dei numeri, mentre richiede solo una piccola quantità di codice per decomprimere.

Le virgole all'inizio e alla fine della stringa rappresentano il modo semplicistico in cui si trovano le sottostringhe all'interno di questa stringa. L'aggiunta di due caratteri qui salva altri caratteri in seguito.

Sull'abuso di main()

argvviene ignorato (e quindi non dichiarato nella versione compressa), il valore di argc viene ignorato, ma la memoria viene riutilizzata per contenere il numero corrente. Questo mi evita di dover dichiarare una variabile extra.

Circa la mancanza di #include

Alcuni si lamenteranno che omettere #include <stdio.h>è barare. Non lo è affatto. Il dato è un programma C completamente legale che verrà compilato correttamente su qualsiasi compilatore C che conosco (anche se con avvertimenti). In mancanza di protoipi per le funzioni stdio, il compilatore presumerà che siano funzioni cdecl che ritornano inte si fiderà che tu sappia quali argomenti passare. I valori di ritorno vengono ignorati in questo programma, comunque, e sono tutte funzioni cdecl (convenzione di chiamata "C"), e sappiamo effettivamente quali argomenti passare.

Produzione

L'output è come previsto:

0
zero è quattro.
quattro è magico.
1
uno fa tre.
tre fa cinque.
cinque fa quattro.
quattro è magico.
4
quattro è magico.
20
venti fa sei.
sei fa tre.
tre fa cinque.
cinque fa quattro.
quattro è magico.
21
ventuno fa nove.
nove fa quattro.
quattro è magico.

* La versione precedente mancava il segno su due parti della specifica: non gestiva lo zero e richiedeva input sulla riga di comando invece che sullo stdin. La gestione degli zeri aggiungeva caratteri, ma l'uso di stdin invece degli argomenti della riga di comando, così come un paio di altre ottimizzazioni, salvava lo stesso numero di caratteri, risultando in un lavaggio.

I requisiti sono stati modificati per chiarire che la parola numerica deve essere stampata su entrambi i lati di "è". Questa nuova versione soddisfa questo requisito e implementa un paio di ottimizzazioni in più per (più di) tenere conto delle dimensioni extra necessarie.


Questo è facilmente il mio preferito della parola risposte ... Bravo, ben fatto. +1 per te, e se potessi dare due segni di spunta lo farei.
Platinum Azure

5
È divertente da leggere, penso che userò questi numeri d'ora in poi nella vita quotidiana. Sei, sem, otto, nove, tel, elem, dodici, enpee, fourpee, fifpee, sixpee, sevenpee, eightoh, ninepee, twelkyu ... =)
inganno

10

J, 107 112 caratteri

'4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.
(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:

(Nuova riga solo per leggibilità)

Utilizzo e output:

    '4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:12
12 is 6.    
6 is 3.     
3 is 5.     
5 is 4.     
4 is magic. 

15
È compilato in cinese
Dr. belisarius il

3
Scegli un arbitro non cinese
Dr. belisarius

3
@beli: 멩, 겻, 곋, 멩 sono coreani.
kennytm

1
Mia moglie (madrelingua cinese) dice che è un misto di cinese e coreano.
Loren Pechtel

3
@belisarius: 1) Non conosce il coreano. 2) Il cinese è senza senso.
Loren Pechtel

10

T-SQL, 413 451 499 caratteri

CREATE FUNCTION d(@N int) RETURNS int AS BEGIN
Declare @l char(50), @s char(50)
Select @l='0066555766',@s='03354435543668877987'
if @N<20 return 0+substring(@s,@N+1,1) return 0+substring(@l,(@N/10)+1,1) + 0+(substring(@s,@N%10+1,1))END
GO
CREATE proc M(@x int) as BEGIN
WITH r(p,n)AS(SELECT p=@x,n=dbo.d(@x) UNION ALL SELECT p=n,n=dbo.d(n) FROM r where n<>4)Select p,'is',n,'.' from r print '4 is magic.'END

(Non che io stia seriamente suggerendo di farlo ... davvero volevo solo scrivere un CTE)

Usare:

M 95

ritorna

p                n
----------- ---- -----------
95          is   10.
10          is   3.
3           is   5.
5           is   4.
4 is magic.

Non puoi semplicemente stampare i risultati individuali invece di restituire una tabella? Ciò renderebbe l'output più gradevole.
Joey

1
Non penso che gestisca correttamente lo zero. Che ne dici di qualcosa del genere:CREATE FUNCTION d(@ int) RETURNS int AS BEGIN Declare @l char(9),@s char(50) Select @l='066555766',@s='03354435543668877987' if @=0 return 4 if @<20 return 0+substring(@s,@+1,1)return 0+substring(@l,@/10,1)+substring(@s,@%10+1,1)END
Gabe

9

Java (con boilerplate), 308 290 286 282 280 caratteri

class A{public static void main(String[]a){int i=4,j=0;for(;;)System.out.printf("%d is %s.%n",i=i==4?new java.util.Scanner(System.in).nextInt():j,i!=4?j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:"magic");}}

Sono sicuro che Groovy si sbarazzerà di gran parte di questo.

Spiegazione e formattazione (tutti i commenti, le nuove righe e gli spazi bianchi iniziali / finali rimossi nel conteggio):

Ragionevolmente semplice, ma

//boilerplate
class A{
   public static void main(String[]a){
      //i is current/left number, j right/next number.  i=4 signals to start
      //by reading input
      int i=4,j=0;
      for(;;)
         //print in the form "<left> is <right>."
         System.out.printf(
            "%d is %s.%n",
            i=i==4?
               //<left>: if i is 4 <left> will be a new starting number
               new java.util.Scanner(System.in).nextInt():
               //otherwise it's the next val
               j,
            i!=4?
               //use string to map number to its length (:;< come after 9 in ASCII)
               //48 is value of '0'.  store in j for next iteration
               j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:
               //i==4 is special case for right; print "magic"
               "magic");
   }
}

Modifica: non utilizzare più esadecimale, questo è un numero minore di sequenze di tasti


1
249 senza importazioni, definizione classe o definizione principale.
Mark Peters

1
È diabolico. Mi piace la base 16. (+1)
Platinum Azure

Puoi risparmiare uno spazio usando String[]ainvece di String[] a.
BalusC

Grazie @Balus, ho anche eliminato un gruppo facendo semplici calcoli aritmetici sul personaggio invece di usare l'analisi esadecimale.
Mark Peters

@ Mark Peters: ancora più cattivo. Mi sento così vanigliato rispetto a quello.
Platinum Azure

9

Windows PowerShell: 152 153 184 byte

basato sulla soluzione precedente, con maggiore influenza da altre soluzioni

$o="03354435543668877988"
for($input|sv b;($a=$b)-4){if(!($b=$o[$a])){$b=$o[$a%10]-48+"66555766"[($a-$a%10)/10-2]}$b-=48-4*!$a
"$a is $b."}'4 is magic.'

Risolto il problema con il supporto di multipli di 10 ("novanta" anziché "novantazero").
Gabe

Hey @Gabe :), grazie; non ho avuto molto tempo per giocare a golf ultimamente. Tuttavia, le virgolette $inputdevono rimanere poiché non è possibile eseguire il cast di un enumeratore direttamente su int; funziona quando si passa per stringprimo :-)
Joey

8

C, 158 caratteri

main(n,c){char*d="03354435543668877988";for(scanf("%d",&n);n-4;n=c)printf("%d is %d.\n",n,c=n?n<19?d[n]-48:d[n%10]-"_,**+++)**"[n/10]:4);puts("4 is magic.");}

(originariamente basato sul codice Python di Vlad, ha preso in prestito un trucco dalla soluzione C ++ di Tom Sirgedas per spremere qualche altro carattere)

versione ampliata:

main(n, c) {
    char *d = "03354435543668877988";
    for (scanf("%d",&n); n-4; n = c)
        printf("%d is %d.\n", n, c = n ? n<19 ? d[n]-48 : d[n%10] - "_,**+++)**"[n/10]  : 4);
    puts("4 is magic.");
}

Non sembra funzionare per me: ./magic 10 10 è -27. Errore di segmentazione
Casey

@Casey - la chiamata scanf () era un po 'imprecisa. Stava leggendo un int in un carattere. Stavo andando via con OSX e su Windows ha funzionato ma si è bloccato all'uscita. Quindi, ho fatto di nuovo intenti n & c. Mi sono reso conto che potevo eliminare la parola chiave int rendendoli parametri utilizzando la notazione K&R. Il risultato è più sicuro e un carattere più corto.
Ferruccio

Puoi salvare 3 caratteri sostituendo " 466555766" [n / 10] + d [n% 10] -96 con d [n% 10] - " , +++) " [n / 10]
Tom Sirgedas

6

Python, 129 133 137 148 chars

Come riscaldamento, ecco la mia prima versione (migliora un paio di caratteri rispetto al precedente miglior Python).

PS. Dopo alcune revisioni ora è una ventina di caratteri più breve:

n=input()
while n-4:p=(922148248>>n/10*3&7)+(632179416>>n%10*3&7)+(737280>>n&1)+4*(n<1);print n,'is %d.'%p;n=p
print'4 is magic.'

6

C #: 210 caratteri.

Schiacciato:

using C=System.Console;class B{static void Main(){int
x=0,y=int.Parse(C.ReadLine());while(x!=4)C.Write((x=y)+" is {0}.\n",x==4?"magic":""+(y=x==0?4:"03354435543668877988"[x<20?x:x%10]+"0066555766"[x/10]-96));}}

Allargato:

using C=System.Console;
class B
{
    static void Main()
    {
        int x=0,y=int.Parse(C.ReadLine());
        while(x!=4)
            C.Write((x=y)+" is {0}.\n",
                x==4?
                     "magic":
                     ""+(y= x==0?
                                4:
                                "03354435543668877988"[x<20?x:x%10]+
                                "0066555766"[x/10]-96)
                   );
    }
}

Trucchi che questo approccio utilizza:

  • Crea una tabella di ricerca per le lunghezze dei nomi dei numeri in base alle cifre che compaiono nel numero.
  • Usa la ricerca della matrice di caratteri su una stringa e l'aritmetica dei caratteri invece di una matrice numerica.
  • Usa l'alias del nome della classe per abbreviare Console.aC.
  • Utilizza l'operatore condizionale (ternario) ( ?:) invece di if/else.
  • Usa il codice \ncon Writeescape invece diWriteLine
  • Utilizzare il fatto che C # ha un ordine di valutazione definito per consentire le assegnazioni all'interno di Write chiamata di funzione
  • Usa le espressioni di assegnazione per eliminare istruzioni extra e quindi parentesi graffe extra

int[] zsarebbe più breve poiché non ha bisogno dinew[]
Joey

Rivisto per utilizzare l'aritmetica dei caratteri invece della ricerca di array.
LBushkin

@ mdm20: hai ragione. Ho avuto un errore nella tabella di ricerca. Risolto ora.
LBushkin

Ebbene, la dodicesima volta è il fascino: * D
LBushkin

Un quicky per salvare 5 caratteri: Shorter di fusione "magic"a object, sarebbe implicitamente chiamare ToString()su yaggiungendo "". Ma, in quanto +ha la precedenza superiore ?:, bisogna metterlo nel vero parte invece della falsa parte: x!=4?y+"":"magic".
P papà

6

Perl: 148 caratteri

(Perl: 233 181 212 206 200 199 198 185 179 149 148 caratteri)

  • Hash delle eccezioni spostato nell'array di unità. Ciò mi ha permesso di tagliare molti personaggi :-)
  • mobrule ha rilevato un brutto bug. La correzione rapida aggiunge 31 caratteri, ahi!
  • Refactored per zero casi speciali, anche per il golf leggero.
  • Accesso diretto all'elenco per uso singolo anziché archiviare nell'array? Diavolo sì!
  • COSÌ TANTO REFACTORING per UN SOLO personaggio insanguinato. Questa, in verità, è la vita di un giocatore di golf. :-(
  • Oops, facile correzione degli spazi bianchi. 198 ora.
  • Refactored del codice ridondante.
  • Ultima parola chiave restituita in r non è necessaria, rasata ancora un po '.
  • Massiccio refactoring per commenti; sfortunatamente sono riuscito a portarlo solo a 149 perché dovevo correggere un bug che era presente sia nel mio codice precedente che nelle versioni dei commentatori.
  • Cercando senza parole "magia".

Facciamo rotolare questa palla con un modesto tentativo in Perl.

@u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
"while$_

Trucchi:

Troppi!


ACK! Come non ho mai provato che non lo saprò mai.
Platinum Azure

Hai un codice morto lì dentro? Non vedo come il caso speciale per zero sia necessario quando $ u [0] è 4. Ho una versione apparentemente funzionante del tuo codice @ 166 caratteri, e penso che abbia spazio per diventare un po 'più corto di quello.
hobbs

@ hobbs: Buon punto, guarderò di nuovo. La storia è che sono arrivato a metà di un paio di revisioni e improvvisamente le cose si sono rotte (all'incirca al punto in cui ho scelto di avere 4 -> 0). Penso che tu abbia ragione a questo punto, però :-)
Platinum Azure

Non mi considero un grande programmatore Perl, ma puoi ridurre alcuni caratteri: le @u=split$x,'43350435543668877988';tue virgole usano 19 caratteri non necessari, dividendosi su una undefdivisione ad ogni carattere, io uso $xcome variabile indefinita per prendere il posto di `undef` - totale risparmio: 11 caratteri. Inoltre, rimuovere l' min chompe si ottiene un altro personaggio rasato il tuo punteggio.
vol7ron

Stai facendo meglio, ma puoi ancora risparmiare di più perdendo sub rcompletamente: lo usi solo una volta e puoi sostituirlo tutto con un singolo ternario annidato senza nemmeno parentesi. La mia versione è 144 caratteri in questo momento: gist.github.com/473289
hobbs

5

JavaScript 1.8 (SpiderMonkey) - 153 caratteri

l='4335443554366887798866555766'.split('')
for(b=readline();(a=+b)-4;print(a,'is '+b+'.'))b=a<20?l[a]:+l[18+a/10|0]+(a%10&&+l[a%10])
print('4 is magic.')

Utilizzo: echo 42 | js golf.js

Produzione:

42 is 8.
8 is 5.
5 is 4.
4 is magic.

Con bonus - 364 caratteri

l='zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ')
z=function(a)a<20?l[a]:l[18+a/10|0]+(a%10?' '+l[a%10]:'')
for(b=+readline();(a=b)-4;print(z(a),'is '+z(b)+'.'))b=z(a).replace(' ','').length
print('four is magic.')

Produzione:

novantanove fa dieci.
dieci fa tre.
tre fa cinque.
cinque fa quattro.
quattro è magico.

4

Haskell, 224 270 caratteri

o="43354435543668877988"
x!i=read[x!!i]
n x|x<20=o!x|0<1="0066555766"!div x 10+o!mod x 10
f x=zipWith(\a b->a++" is "++b++".")l(tail l)where l=map show(takeWhile(/=4)$iterate n x)++["4","magic"]
main=readLn>>=mapM putStrLn.f

E un po 'più leggibile -

ones = [4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8]
tens = [0,0,6,6,5,5,5,7,6,6]

n x = if x < 20 then ones !! x else (tens !! div x 10) + (ones !! mod x 10)

f x = zipWith (\a b -> a ++ " is " ++ b ++ ".") l (tail l)
    where l = map show (takeWhile (/=4) (iterate n x)) ++ ["4", "magic"]
    
main = readLn >>= mapM putStrLn . f

4

Versione C ++ Stdio, ridotta: 196 caratteri

#include <cstdio>
#define P;printf(
char*o="43354435543668877988";main(int p){scanf("%d",&p)P"%d",p);while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]P" is %d.\n%d",p,p);}P" is magic.\n");}

Versione C ++ Iostreams, ridotta: 195 caratteri

#include <iostream>
#define O;std::cout<<
char*o="43354435543668877988";main(int p){std::cin>>p;O p;while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]O" is "<<p<<".\n"<<p;}O" is magic.\n";}

Originale, non minimizzato: 344 caratteri

#include <cstdio>

int ones[] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8 };
int tens[] = { 0, 3, 6, 6, 5, 5, 5, 9, 6, 6 };

int n(int n) {
    return n<20 ? ones[n] : tens[n/10] + ones[n%10];
}

int main(int p) {
    scanf("%d", &p);
    while(p!=4) {
        int q = n(p);
        printf("%i is %i\n", p, q);
        p = q;
    }
    printf("%i is magic\n", p);
}

Fisso. Lo ha reso anche un po 'più corto.
Mike DeSimone

Ben fatto. (Ho riso molto all'enigma standard di 20 caratteri!)
Platinum Azure

Sì, è stato un vero e proprio headbanger, finché non mi sono reso conto che #definesarebbe stato ancora più breve dato che avrebbe potuto sostituire diversi gettoni.
Mike DeSimone

printf("is magic".\n)=> puts. printf("%d",p)=> puts(atoi(p)). Non solo più corto ma anche più veloce.
Ben Voigt

2
@ Mike DeSimone: penso che while(p!=4)potrebbe essere abbreviato in while(p-4). Un intero personaggio, lo so, ma comunque. :-)
Platinum Azure

3

Delphi: 329 caratteri

Versione a riga singola:

program P;{$APPTYPE CONSOLE}uses SysUtils;const S=65;A='EDDFEEDFFEDGGIIHHJII';B='DGGFFFJGG';function Z(X:Byte):Byte;begin if X<20 then Z:=Ord(A[X+1])-S else Z:=(Ord(B[X DIV 10])-S)+Z(X MOD 10)end;var X,Y:Byte;begin Write('> ');ReadLn(X);repeat Y:=Z(X);WriteLn(Format('%d is %d.',[X,Y]));X:=Y;until X=4;WriteLn('4 is magic.');end.

Formata:

program P;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  S = 65;
  A = 'EDDFEEDFFEDGGIIHHJII';
  B = 'DGGFFFJGG';

function Z(X:Byte):Byte;
begin
  if X<20
  then Z := Ord(A[X+1])-S
  else Z := (Ord(B[X DIV 10])-S) + Z(X MOD 10);
end;

var
  X,Y: Byte;

begin
  Write('> ');
  ReadLn(X);

  repeat
    Y:=Z(X);
    WriteLn(Format('%d is %d.' , [X,Y]));
    X:=Y;
  until X=4;

  WriteLn('4 is magic.');
end.

Probabilmente spazio per qualche altra spremitura ... :-P


3

C # 314 286 283 274 289 273 252 caratteri.

Schiacciato:

252 

Normale:

using C = System.Console;
class P
{
    static void Main()
    {
        var x = "4335443554366877798866555766";
        int m, o, v = int.Parse(C.ReadLine());
        do {
            C.Write("{0} is {1}.\n", o = v, v == 4 ? (object)"magic" : v = v < 20 ? x[v] - 48 : x[17 + v / 10] - 96 + ((m = v % 10) > 0 ? x[m] : 48));
        } while (o != 4);
        C.ReadLine();
    }
}

Modifica Dykam: ha apportato alcune modifiche e inserimenti accurati:

  • Modificato l.ToString () in un cast objectdistring "magic" .
  • oHo creato una variabile temporanea , quindi ho potuto spostare l' breakesterno del forciclo, cioè risultando in un filedo-while .
  • Inline l' oassegnazione, così come l' vassegnazione, continuando a inserire del tutto il calcolo di lnegli argomenti della funzione, eliminando la necessità di l. Inline anche l'assegnazione di m.
  • Rimosso uno spazio in int[] x, int[]xè anche legittimo.
  • Ho provato a trasformare l'array in una trasformazione di stringa, ma using System.Linqera troppo per renderlo un miglioramento.

Modifica 2 Dykam Modificato l'array int in un array / stringa di caratteri, aggiunti aritmici appropriati per correggere questo problema.


Sì, è più breve della versione Java.
Dykam

3

Lua, 176 caratteri

o={[0]=4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}t={3,6,6,5,5,5,7,6,6}n=0+io.read()while n~=4 do a=o[n]or o[n%10]+t[(n-n%10)/10]print(n.." is "..a..".")n=a end print"4 is magic."

o

  o={[0]=4,3,3,5,4,4
  ,3,5,5,4,3,6,6,8,8
  ,7,7,9,8,8}t={3,6,
   6,5,5,5,7,6,6}n=
   0+io.read()while
   n ~= 4 do a= o[n
   ]or o[n%10]+t[(n
   -n%10)/10]print(
n.." is "..a.."." )n=a
end print"4 is magic."

3

C - senza parole numeriche

180 175 * 172 167 caratteri

Tutte le nuove righe sono leggibili e possono essere rimosse:

i;V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}main(c){for(scanf("%d",&c);
c-4;)i=c,printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);puts(
"4 is magic.");}

Leggermente non minimizzato:

i;
V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}
main(c){
    for(scanf("%d",&c);c-4;)
        i=c,
        printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);
    puts("4 is magic.");
}

* La versione precedente mancava il segno su due parti delle specifiche: non gestiva lo zero e richiedeva input sulla riga di comando invece che sullo stdin. La gestione di zero caratteri aggiunti, ma l'utilizzo di stdin al posto degli argomenti della riga di comando ha risparmiato ancora di più, con un risparmio netto.


2

perl, 123 122 caratteri

Mi sono appena reso conto che non è necessario eseguire l'output su STDOUT, quindi esegui l'output su STDERR e elimina un altro carattere.

@u='0335443554366887798866555766'=~/./g;$_+=<>;warn"$_ is ",$_=$_-4?$_<20?$u[$_]||4:$u[chop]+$u[$_+18]:magic,".\n"until/g/

E, una versione che restituisce numeri scritti:

279 278 276 280 caratteri

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2] $n[$n%10]":Zero}$p+=<>;warnt$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

Sebbene soddisfi le specifiche, non è ben formattato al 100%. Restituisce uno spazio aggiuntivo dopo i numeri che terminano con zero. La specifica dice:

"Non mi interessa come separare le parole token, anche se dovrebbero essere separate"

Questo è un po 'malizioso però. Una versione più corretta in

282 281 279 283 caratteri

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("\x8",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2]-$n[$n%10]":Zero}$p+=<>;warn$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

1

Pitone:

#!/usr/bin/env python

# Number of letters in each part, we don't count spaces
Decades = ( 0, 3, 6, 6, 6, 5, 5, 7, 6, 6, 0 )
Smalls  = ( 0, 3, 3, 5, 4, 4, 3, 5, 5, 4 )
Teens  =  ( 6, 6, 8, 8, 7, 7, 9, 8, 8 )

def Count(n):
    if n > 10 and n < 20: return Teens[n-11]
    return   Smalls[n % 10 ] + Decades [ n / 10 ]

N = input()

while N-4:
    Cnt = Count(N)
    print "%d is %d" % ( N, Cnt)
    N = Cnt

print "4 is magic"

4
Mi piace. Probabilmente potresti stringere un po 'però.
Josh K

@Vlad: l'input dovrebbe essere letto da stdin invece dagli argomenti. Ciò significa che potresti semplicemente usare N = input()(o raw_input()) ed eliminare il sysmateriale.
kennytm

Inoltre potresti fare in modo che i piccoli includano gli adolescenti, quindi l'istruzione if sarebbe solo "if n <20: return Smalls [n]". Smalls funzionerebbe ancora per il caso> = 20, a causa del modulo di 10.
Jon Smock

5
Questa deve essere la prima volta che vedo il (completamente opzionale) she-bangin una risposta da golf in codice ;-)
ChristopheD

Sembra un buon inizio ... Sicuramente rafforzalo, anche Python non ha bisogno di TUTTO questo spazio bianco. :-) Inoltre, come sottolinea Ferruccio, 0 non funziona, nello specifico sembra entrare in un loop infinito.
Platinum Azure

1

C ++, 171 caratteri (#include omesso)

void main(){char x,y,*a="03354435543668877988";scanf("%d",&x);for(;x-4;x=y)y=x?x<19?a[x]-48:"_466555766"[x/10]+a[x%10]-96:4,printf("%d is %d.\n",x,y);puts("4 is magic.");}

Penso che se lo consideri C, puoi evitare la necessità del #includeperché si presume che le funzioni prendano solo intparametri. Puoi anche salvare un colpo facendo mainritorno int.
Gabe

1

Ruby, 164 caratteri

n=gets.to_i;s="03354435543668877987";if n==0;puts"0 is 4.";else;puts"#{n} is #{n=(n<20)?s[n]-48:"0066555766"[n/10]-48+s[n%10]-48}." until n==4;end;puts"4 is magic."

decodificato:

n = gets.to_i
s = "03354435543668877987"
if n == 0
  puts "0 is 4."
else
  puts "#{n} is #{n = (n < 20) ? s[n] - 48 : "0066555766"[n / 10] - 48 + s[n % 10] - 48}." until n == 4
end

puts "4 is magic."

Bella soluzione Ruby, mantenendola semplice. :-) (+1)
Platinum Azure

Mantenerlo semplice non è una scusa per mantenerlo eccessivamente lungo, però ;-)
Joey

Penso che tu possa sostituire "if n == 0" con "if! N"
Vincent

2
In Ruby? Ho sempre pensato che tutti i valori eccetto false e nil fossero veri :-(
Platinum Azure

1

Lua 185 190 199

punti aggiunti, aggiunto io.read, rimosso () sull'ultima stampa

 n=io.read();while(n~=4)do m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;print(n,' is ',m,'.')n=m;end print'4 is magic.'

con interruzioni di riga

 n=io.read()
 while (n~=4) do
    m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;
    print(n,' is ',m,'.')
    n=m;
 end 
 print'4 is magic.'

Richiede un n=io.read()(+11 caratteri) per rispettare la regola per leggere il numero dallo standard input. Il passaggio print('4 is magic.')a print'4 is magic.'salverà 2 caratteri. La rimozione ;dopo )salverà 1 carattere. L' printuso delle virgole sembra un inganno, ma le specifiche non sono chiare. Tanto vale cambiarlo in print(n,'is',m,'.')per salvare 2 caratteri.
gwell

Le virgole vengono visualizzate come nuove righe in Lua? È passato un po 'di tempo da quando l'ho usato.
Nick Van Brunt

Le virgole vengono visualizzate come tabulazioni.
gwell

0

Codice PhP

function get_num_name($num){  
    switch($num){  
        case 1:return 'one';  
    case 2:return 'two';  
    case 3:return 'three';  
    case 4:return 'four';  
    case 5:return 'five';  
    case 6:return 'six';  
    case 7:return 'seven';  
    case 8:return 'eight';  
    case 9:return 'nine';  
    }  
}  

function num_to_words($number, $real_name, $decimal_digit, $decimal_name){  
    $res = '';  
    $real = 0;  
    $decimal = 0;  

    if($number == 0)  
        return 'Zero'.(($real_name == '')?'':' '.$real_name);  
    if($number >= 0){  
        $real = floor($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }else{  
        $real = ceil($number) * (-1);  
        $number = abs($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }  
    $decimal = substr($decimal, strpos($decimal, '.') +1);  

    $unit_name[1] = 'thousand';  
    $unit_name[2] = 'million';  
    $unit_name[3] = 'billion';  
    $unit_name[4] = 'trillion';  

    $packet = array();    

    $number = strrev($real);  
    $packet = str_split($number,3);  

    for($i=0;$i<count($packet);$i++){  
        $tmp = strrev($packet[$i]);  
        $unit = $unit_name[$i];  
        if((int)$tmp == 0)  
            continue;  
        $tmp_res = '';  
        if(strlen($tmp) >= 2){  
            $tmp_proc = substr($tmp,-2);  
            switch($tmp_proc){  
                case '10':  
                    $tmp_res = 'ten';  
                    break;  
                case '11':  
                    $tmp_res = 'eleven';  
                    break;  
                case '12':  
                    $tmp_res = 'twelve';  
                    break;  
                case '13':  
                    $tmp_res = 'thirteen';  
                    break;  
                case '15':  
                    $tmp_res = 'fifteen';  
                    break;  
                case '20':  
                    $tmp_res = 'twenty';  
                    break;  
                case '30':  
                    $tmp_res = 'thirty';  
                    break;  
                case '40':  
                    $tmp_res = 'forty';  
                    break;  
                case '50':  
                    $tmp_res = 'fifty';  
                    break;  
                case '70':  
                    $tmp_res = 'seventy';  
                    break;  
                case '80':  
                    $tmp_res = 'eighty';  
                    break;  
                default:  
                    $tmp_begin = substr($tmp_proc,0,1);  
                    $tmp_end = substr($tmp_proc,1,1);  

                    if($tmp_begin == '1')  
                        $tmp_res = get_num_name($tmp_end).'teen';  
                    elseif($tmp_begin == '0')  
                        $tmp_res = get_num_name($tmp_end);  
                    elseif($tmp_end == '0')  
                        $tmp_res = get_num_name($tmp_begin).'ty';  
                    else{  
                        if($tmp_begin == '2')  
                            $tmp_res = 'twenty';  
                        elseif($tmp_begin == '3')  
                            $tmp_res = 'thirty';  
                        elseif($tmp_begin == '4')  
                            $tmp_res = 'forty';  
                        elseif($tmp_begin == '5')  
                            $tmp_res = 'fifty';  
                        elseif($tmp_begin == '6')  
                            $tmp_res = 'sixty';  
                        elseif($tmp_begin == '7')  
                            $tmp_res = 'seventy';  
                        elseif($tmp_begin == '8')  
                            $tmp_res = 'eighty';  
                        elseif($tmp_begin == '9')  
                            $tmp_res = 'ninety';  

                        $tmp_res = $tmp_res.' '.get_num_name($tmp_end);  
                    }  
                    break;  
            }  

            if(strlen($tmp) == 3){  
                $tmp_begin = substr($tmp,0,1);  

                $space = '';  
                if(substr($tmp_res,0,1) != ' ' && $tmp_res != '')  
                    $space = ' ';  

                if($tmp_begin != 0){  
                    if($tmp_begin != '0'){  
                        if($tmp_res != '')  
                            $tmp_res = 'and'.$space.$tmp_res;  
                    }  
                    $tmp_res = get_num_name($tmp_begin).' hundred'.$space.$tmp_res;  
                }  
            }  
        }else  
            $tmp_res = get_num_name($tmp);  
        $space = '';  
        if(substr($res,0,1) != ' ' && $res != '')  
            $space = ' ';  
        $res = $tmp_res.' '.$unit.$space.$res;  
    }  

    $space = '';  
    if(substr($res,-1) != ' ' && $res != '')  
        $space = ' ';  

    if($res)  
        $res .= $space.$real_name.(($real > 1 && $real_name != '')?'s':'');  

    if($decimal > 0)  
        $res .= ' '.num_to_words($decimal, '', 0, '').' '.$decimal_name.(($decimal > 1 && $decimal_name != '')?'s':'');  
    return ucfirst($res);  
}  

//////////// test ////////////////

 $str2num = 12;
    while($str2num!=4){
        $str = num_to_words($str2num, '', 0, '');  
        $str2num = strlen($str)-1;
        echo $str . '=' . $str2num .'<br/>';
        if ($str2num == 4)
            echo 'four is magic';
    }

////// Risultati /////////

Twelve =6
Six =3
Three =5
Five =4
four is magic

4
@wallacoloo: Una soluzione scadente per un linguaggio scadente: D
Thomas Eding

5
O un 178 caratteri molto più breve:$l='4335443554366887798866555766';for($b=(int)fgets(fopen('php://stdin','r'));($a=$b)-4;){$b=$a<20?$l[$a]:$l[18+$a/10]+($a%10?$l[$a%10]:0);echo"$a is $b.\n";}echo"4 is magic.\n";
gnarf

Bello scherzo. MrGreen Così ben programmato.
Tom Pažourek

0

Perl - 130 caratteri


5.12.1 (130 caratteri) 121 123 132 136 140

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123

@u='4335443554366887798866555766'=~/./g;$_=pop;say"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,"."until/\D/


5.10.1 (134 caratteri) 125 127 136 140 144

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234

@u='4335443554366887798866555766'=~/./g;$_=pop;print"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,".\n"until/\D/


Cambiare la storia:

20100714:2223- modifica annullata all'attenzione di mobrule , ma ($_%10&&$u[$_%10])(($_%=10)&&$u[$_]), che è lo stesso numero di caratteri, ma l'ho fatto nel caso qualcuno potesse vedere un modo per migliorarlo

20100714:0041- split//,'...''...'=~/./g
20100714:0025- ($_%10&&$u[$_%10])$u[$_%10]
20100713:2340- while$_until/\D/+ rimosse le parentesi non necessarie
20100713:xxxx- $=<>;chop;$_=pop;- per gentile concessione di mobrule


Nota: ero stanco di migliorare le risposte degli altri nei commenti, quindi ora sono avido e posso semplicemente aggiungere le mie modifiche qui :) Questa è una separazione dalla risposta di Platinum Azure - credito in parte a Hobbs , mobrule e Platinum Azure .


Quando ti sei sbarazzato del $_%10&&...costrutto, hai infranto le specifiche per gli input 20,30,40, ...
mob

+1 Ben fatto. Sei uscito dallo stdin in args però :-(
Platinum Azure

Giusto, sostituito con ARGV, che è popolato da STDIN:) o .. echo bar | xargs perl foo.pl, tecnicamente convogliato da echo in args for perl :)
vol7ron

0

Perl senza vergogna con parole numeriche (329 caratteri)

Adattato abbastanza direttamente dal codice C di P Daddy, con alcune modifiche per p()farlo fare la stessa cosa usando le primitive Perl invece di quelle C, e un mainloop per lo più riscritto. Vedere il suo per una spiegazione. Le nuove righe sono tutte facoltative.

@t=(qw(zero one two three four five six sM eight nine
tL elM twelve NP 4P fifP 6P 7P 8O 9P twLQ NQ forQ fifQ
6Q 7Q 8y 9Q en evL thir eL tO ty 4SmagicT)," is ",".\n");
sub p{local$_=$t[pop];1while s/[0-Z]/$t[-48+ord$&]/e;
print;length}$_=<>;chop;while($_-4){
$_=($_>19?(p($_/10+18),$_&&print("-"),$_%=10)[0]:0)+p$_;
p 35;p$_;p 36}p 34

Nota a margine: è un peccato che perl printrestituisca solo vero / falso; se restituisse un conteggio mi risparmierebbe 7 colpi.


0

Rubino, 141 caratteri:

n=gets.to_i;m="4335443554366887798866555766";loop{s=n;n=n>20?m[18+n/10]+m[n%10]-96: m[n]-48;puts"#{s} is #{n==s ? 'magic': n}.";n==s &&break}

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.