Code Golf: Cuatro es mágico

88

El rompecabezas

Un pequeño acertijo que escuché mientras estaba en la escuela secundaria fue algo como esto ...

  • El interlocutor me pedía que le diera un número;
  • Al escuchar el número, el interrogador haría algún tipo de transformación en él repetidamente (por ejemplo, podría decir que diez es tres ) hasta llegar al número 4 (momento en el que terminaría con cuatro es mágico ).
  • Cualquier número parece transformarse eventualmente en cuatro, pase lo que pase.

El objetivo era intentar descubrir la función de transformación y luego poder supervisar este rompecabezas de manera confiable.

La solución

La función de transformación en cualquier paso era

  • Tome el número en cuestión,
  • Cuente el número de letras en su representación de palabras en inglés, ignorando un guión o espacios o "y" (por ejemplo, "diez" tiene 3 letras, "treinta y cuatro" tiene 10 letras, "ciento cuarenta y tres" tiene 20 letras).
  • Devuelve ese número de letras.

Para todos los números que he querido probar, esto converge a 4. Dado que "cuatro" también tiene cuatro letras, habría un bucle infinito aquí; en cambio, simplemente se lo conoce como magia por convención para finalizar la secuencia.

El reto

Su desafío es crear un fragmento de código que lea un número del usuario y luego imprima líneas que muestren la función de transformación que se aplica repetidamente hasta que se alcance "cuatro es mágico".

Específicamente:

  1. Las soluciones deben ser programas completos en sí mismos. No pueden ser simplemente funciones que incorporan un factor numérico en la entrada.
  2. La entrada debe leerse desde la entrada estándar. (La canalización desde "echo" o el uso de la redirección de entrada está bien, ya que también va desde stdin)
  3. La entrada debe estar en forma numérica.
  4. Para cada aplicación de la función de transformación, se debe imprimir una línea: a is b. donde ayb son formas numéricas de los números en la transformación.
  5. ¡Se requieren paradas completas (puntos)!
  6. La última línea debería decir naturalmente, 4 is magic. .
  7. El código debe producir una salida correcta para todos los números del 0 al 99 .

Ejemplos:

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

El ganador es el envío más corto por número de caracteres del código fuente, que también es correcto .

PRIMA

También puede intentar escribir una versión del código que imprima los NOMBRES EN INGLÉS de los números con cada aplicación de la función de transformación. La entrada original sigue siendo numérica, pero las líneas de salida deben tener la forma de palabra del número.

(Doble bonificación por dibujar formas con su código)

(EDITAR) Algunas aclaraciones:

  1. Quiero que la palabra aparezca en ambos lados en todos los casos aplicables, p. Ej. Nine is four. Four is magic.
  2. Sin embargo, no me importa el uso de mayúsculas. Y no me importa cómo separa la palabra tokens, aunque deberían estar separados: ninety-nineestá bien, ninety nineestá bien, ninetynineno está bien.

Considero que estas son una categoría separada para la competencia de bonificación con respecto al desafío, por lo que si opta por esto, no se preocupe si su código es más largo que la versión numérica.

No dude en enviar una solución para cada versión.

Platinum Azure
fuente
1
¿Qué número debemos manejar? <100? <1000? <1000000? <2 ** 31?
P Daddy
1
Dado que esto solo tiene que ir de 0 a 99, sospecho que una solución rápida y corta sería codificar los valores a los que se asignan 0-99 y luego repetir hasta llegar a 4. Después de eso, comienza el microdebilitamiento.
Beska
@P Daddy ... la parte 6 dice solo 0-99.
Beska
14
4 es solo mágico porque fue elegido con una tirada de dados justa.
VirtuosiMedia

Respuestas:

57

GolfScript - 101 96 93 92 91 90 94 86 bytes

90 → 94: Salida fija para múltiplos de 10
94 → 86.: Código reestructurado. Usando base 100 para eliminar caracteres no imprimibles.
86 → 85: Lanzamiento más corto a la cuerda.

{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."
Nabb
fuente
¿Por qué esto está tan abajo? es más corto que el lisp y no usa una función de formato incorporada
Claudiu
36
Me gusta cómo termina el código "magic.", lo resume bastante bien.
Aistina
@Aistina: Eso es fácil de hacer en este desafío, creo. :-)
Platinum Azure
9
@Aistina: jaja, eso es un poco gracioso. "mumbo jumbo yada yada..magic"
vol7ron
1
@P Daddy The des extraído por el )as 100y se usa como base para la conversión base.
Nabb
85

Perl, aproximadamente 147 caracteres

Basado libremente en la solución de 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
mob
fuente
1
@Platinum Azure la forma en que esto obtiene su entrada es mediante el uso de pop, sin ningún argumento. Fuera de una subrutina pop, elimina y devuelve el último valor del @ARGVcual es la lista de argumentos al programa Perl. Podría reemplazarse fácilmente con shift, pero eso agrega otros 2 caracteres. Ver: p3rl.org/pop
Brad Gilbert
parece que necesita un carácter de nueva línea '.', que es 2 para \no 1 si está contando espacios en blanco en el '. '(el espacio es el literal de nueva línea)
vol7ron
Un poco más, pero la creatividad es muy útil en mi libro.
Beska
@Platinum Azure et al: recibe su opinión de stdin. Esa es la forma de hacerlo en Perl. (¿Quizás lo cambió después de tu comentario?)
Frank
@P Daddy: gemido pero +1 a tu comentario de todos modos
Platinum Azure
30

Common Lisp 157 caracteres

Nueva versión más conforme, ahora leyendo la entrada estándar de forma e ignorando espacios y guiones:

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

En forma legible por humanos:

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

Y algunas pruebas se ejecutan:

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

Y la versión adicional, con 165 caracteres:

 (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.
user110763
fuente
5
Pensé que "veinticuatro" solo tiene 10 letras.
kennytm
1
Los números después de "es" también deben ser texto.
Mike DeSimone
5
¿Por qué es esto tan alto? otros no usan una función de formato incorporada y tienen menos caracteres
Claudiu
3
@Claudiu Porque Common Lisp es increíble.
Mornedhel
3
No importa cuántos golpes dé si no mete la bola en el hoyo. La gente parece olvidar eso cuando vota a favor de las soluciones incorrectas.
Mark Peters
21

Python 2.x, 144 150 154 166 caracteres

Esto separa el número en decenas y unidades y los suma. Aquí se abusa de la propiedad indeseable del operador pseudoternario a and b or cque cse devuelve si bes 0.

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 versión ingenua anterior (150 caracteres). Simplemente codifique todas las longitudes como un número entero.

n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."
KennyTM
fuente
Lo siento, específicamente quería puntos completos solo por cosas como esta. :-) ¡Buena entrada! (EDITAR: No sé Python, pero ¿podrías n,"is",p,"."? Creo que todavía guardas algunos personajes si estoy contando bien)
Platinum Azure
2
@Plat: Eso causaría un espacio adicional antes del ..
kennytm
@KennyTM: Oh, duh, debería haberlo notado incluso en el fragmento. ¡Ups! Bueno, de todos modos, como dije, algunas de las especificaciones fueron diseñadas específicamente para complicar un poco las cosas. :-)
Platinum Azure
¿Podemos acortar esto usando una base superior a 36?
MikeD
@MikeD: No. De los documentos de Python: "El parámetro base proporciona la base para la conversión (que es 10 por defecto) y puede ser cualquier número entero en el rango [2, 36] o cero". Ahora es posible que pueda usar una función que no sea int(), decir algo fuera de los módulos structo base64...
Mike DeSimone
20

C - con palabras numéricas

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

Eso es. No creo que pueda hacer esto más corto.

Todas las líneas nuevas son para facilitar la lectura y se pueden eliminar:

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

A continuación, está un poco simplificado, pero sigue siendo bastante difícil de leer. Consulte a continuación para obtener una versión más legible.

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

Ampliado y comentado:

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"*/);
}

Acerca de la cadena codificada cerca del principio

Los nombres de los números se comprimen utilizando un esquema muy simple. Las subcadenas de uso frecuente se reemplazan con índices de un carácter en la matriz de nombres. Se agrega una "tabla de búsqueda" de entradas de nombre adicionales al final para las subcadenas que no se usan en su totalidad en el primer conjunto. Las búsquedas son recursivas: las entradas pueden hacer referencia a otras entradas.

Por ejemplo, el nombre comprimido de 11 es elM. La print()función genera los caracteres ey l(minúscula 'L', no el número '1') literalmente, pero luego encuentra el M, por lo que se llama a sí mismo con el índice de la entrada 29 (ASCII 'M' - ASCII '0') en la tabla de búsqueda. Esta cadena es evL, por lo que genera ey v, luego, se vuelve a llamar a sí misma con el índice de la entrada 28 en la tabla de búsqueda, que es eny es salida textualmente. Esto es útil porque entambién se usa en eLfor een(usado después de eightin eighteen), que se usa en tOfor teen(usado para cualquier otro -teennombre).

Este esquema da como resultado una compresión bastante significativa de los nombres de los números, mientras que solo requiere una pequeña cantidad de código para descomprimir.

Las comas al principio y al final de la cadena representan la forma simplista en que las subcadenas se encuentran dentro de esta cadena. Agregar dos caracteres aquí guarda más caracteres más adelante.

Sobre el abuso de main()

argvse ignora (y por lo tanto no se declara en la versión comprimida), el valor de argc se ignora, pero el almacenamiento se reutiliza para contener el número actual. Esto simplemente me ahorra tener que declarar una variable adicional.

Sobre la falta de #include

Algunos se quejarán de que omitir #include <stdio.h>es hacer trampa. No lo es en absoluto. El dado es un programa en C completamente legal que se compilará correctamente en cualquier compilador de C que conozca (aunque con advertencias). Al carecer de prototipos para las funciones stdio, el compilador asumirá que son funciones cdecl regresando int, y confiará en que usted sabe qué argumentos pasar. Los valores de retorno se ignoran en este programa, de todos modos, y todos son funciones cdecl (convención de llamada "C"), y de hecho sabemos qué argumentos pasar.

Salida

El resultado es el esperado:

0
cero es cuatro.
cuatro es mágico.
1
uno es tres.
tres son cinco.
cinco son cuatro.
cuatro es mágico.
4
cuatro es mágico.
20
veinte son seis.
seis son tres.
tres son cinco.
cinco son cuatro.
cuatro es mágico.
21
veintiuno son nueve.
nueve son cuatro.
cuatro es mágico.

* La versión anterior no alcanzó la marca en dos partes de la especificación: no manejó cero y tomó entrada en la línea de comando en lugar de stdin. El manejo de ceros agregó caracteres, pero el uso de stdin en lugar de argumentos de línea de comando, así como un par de otras optimizaciones, guardaron la misma cantidad de caracteres, lo que resultó en un lavado.

Los requisitos se han cambiado para dejar en claro que la palabra del número debe imprimirse en ambos lados de "es". Esta nueva versión cumple con ese requisito e implementa un par de optimizaciones más para tener en cuenta (más) el tamaño adicional necesario.

P Papi
fuente
Esta es fácilmente mi respuesta favorita de las palabras ... Bravo, bien hecho. +1 para ti, y si pudiera dar dos marcas de verificación, lo haría.
Platinum Azure
5
Es divertido de leer, creo que a partir de ahora usaré estos números en la vida diaria. Seis, sem, ocho, nueve, tel, elem, doce, enpee, fourpee, fivepee, sixpee, sevenpee, eightoh, ninepee, twelkyu ... =)
deceze
10

J, 107 112 caracteres

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

(Nueva línea solo para facilitar la lectura)

Uso y salida:

    '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. 
David
fuente
15
Está compilado en chino
Dr. belisarius
3
Elija un árbitro que no sea chino
Dr. belisarius
3
@beli: 멩, 겻, 곋, 멩 son coreanos.
kennytm
1
Mi esposa (una hablante nativa de chino) dice que es una mezcla de chino y coreano.
Loren Pechtel
3
@belisarius: 1) No sabe coreano. 2) El chino es un galimatías.
Loren Pechtel
10

T-SQL, 413 451 499 caracteres

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

(No es que esté sugiriendo seriamente que hagas esto ... realmente solo quería escribir un CTE)

Usar:

M 95

Devoluciones

p                n
----------- ---- -----------
95          is   10.
10          is   3.
3           is   5.
5           is   4.
4 is magic.
Leon Bambrick
fuente
¿No puede simplemente imprimir los resultados individuales en lugar de devolver una tabla? Eso haría que la salida se viera mejor.
Joey
1
No creo que maneje el cero correctamente. ¿Qué tal algo como esto: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 repetitivo), 308 290 286 282 280 caracteres

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

Estoy seguro de que Groovy se desharía de mucho de eso.

Explicación y formato (todos los comentarios, nuevas líneas y espacios en blanco iniciales / finales eliminados en el recuento):

Razonablemente sencillo, pero

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

Editar: Ya no use hexadecimal, esto es menos pulsaciones de teclas

Mark Peters
fuente
1
249 sin importaciones, def. De clase o def. Principal.
Mark Peters
1
Eso es diabólico. Me gusta la base 16. (+1)
Platinum Azure
Puede ahorrar un espacio usando en String[]alugar de String[] a.
BalusC
Gracias @Balus, también eliminó un montón haciendo aritmética simple en el carácter en lugar de usar análisis hexadecimal.
Mark Peters
@Mark Peters: Aún más desagradable. Me siento tan vainilla en comparación con eso.
Azur platino
9

Windows PowerShell: 152 153 184 bytes

basado en la solución anterior, con más influencia de otras soluciones

$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.'
Јοеу
fuente
Se corrigió para admitir múltiplos de 10 ("noventa" en lugar de "noventa y cero").
Gabe
Hola @Gabe :), gracias; No he tenido mucho tiempo para jugar al golf últimamente. Aún así, las comillas $inputdeben permanecer ya que no puede enviar un enumerador directamente a int; funciona cuando se pasa stringprimero :-)
Joey
8

C, 158 caracteres

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

(originalmente basado en el código Python de Vlad, tomó prestado un truco de la solución C ++ de Tom Sirgedas para exprimir algunos caracteres más)

versión ampliada:

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.");
}
13 revoluciones
fuente
No parece funcionar para mí: ./magic 10 10 es -27. Falla de segmentación
Casey
@Casey: la llamada a scanf () fue un poco incompleta. Estaba leyendo un int en un char. Me estaba saliendo con la suya en OSX y en Windows funcionó, pero se bloqueó al salir. Entonces, hice n & c ints nuevamente. Me di cuenta de que podía eliminar la palabra clave int haciéndolos parámetros usando la notación K&R. El resultado es más seguro y un carácter más corto.
Ferruccio
Puede guardar 3 caracteres reemplazando " 466555766" [n / 10] + d [n% 10] -96 con d [n% 10] - " , +++) " [n / 10]
Tom Sirgedas
6

Pitón, 129 133 137 148 caracteres

Como calentamiento, aquí está mi primera versión (mejora un par de caracteres sobre el mejor Python anterior).

PD. Después de algunas redacciones, ahora es aproximadamente veinte caracteres más corto:

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.'
Nas Banov
fuente
6

C #: 210 caracteres.

Aplastado:

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

Expandido:

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

Trucos que utiliza este enfoque:

  • Cree una tabla de búsqueda para las longitudes de los nombres de los números según los dígitos que aparecen en el número.
  • Utilice la búsqueda de matriz de caracteres en una cadena y la aritmética de caracteres en lugar de una matriz numérica.
  • Utilice alias de nombre de clase para abreviar Console.aC.
  • Utilice el operador condicional (ternario) ( ?:) en lugar de if/else.
  • Utilice \ncon el Writecódigo de escape en lugar deWriteLine
  • Utilice el hecho de que C # tiene un orden definido de evaluación para permitir asignaciones dentro del Write llamada a función
  • Utilice las expresiones de asignación para eliminar declaraciones adicionales y, por lo tanto, llaves adicionales
LBushkin
fuente
int[] zsería más corto ya que no necesita elnew[]
Joey
Revisado para usar aritmética de caracteres en lugar de búsqueda de matrices.
LBushkin
@ mdm20: Tienes razón. Tuve un error en la tabla de búsqueda. Arreglado ahora.
LBushkin
Bueno, la duodécima vez es el encanto: * D
LBushkin
Un QUICKY para guardar 5 caracteres: De menor longitud que la fundición "magic"a object, sería implícitamente llamar ToString()en yañadiendo "". Pero, a causa +tiene mayor precedencia que ?:, hay que ponerlo en la verdadera parte en lugar de la falsa parte: x!=4?y+"":"magic".
P Daddy
6

Perl: 148 caracteres

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

  • Se movió el hash de excepciones a la matriz de unidades. Esto resultó en que pudiera cortar muchos personajes :-)
  • mobrule señaló un error desagradable. La solución rápida agrega 31 caracteres, ¡ay!
  • Refactorado para cero casos especiales, golf suave también hecho.
  • ¿Acceso directo a la lista para un solo uso en lugar de almacenarlo en una matriz? ¡Oh sí!
  • MUCHO REFACTOR para un solo personaje sangriento. Ésta, verdaderamente, es la vida de un golfista. :-(
  • Vaya, fácil corrección de espacios en blanco. 198 ahora.
  • Refactorizó algún código redundante.
  • La última palabra clave de retorno res innecesaria, se ha reducido un poco más.
  • Refactorización masiva por comentarios; desafortunadamente, solo pude llevarlo a 149 porque tuve que corregir un error que estaba presente tanto en mi código anterior como en las versiones de los comentaristas.
  • Probar la palabra "magia".

Hagamos rodar esta bola con un modesto intento en Perl.

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

Trucos:

¡Demasiados!

Platino Azure
fuente
¡ACK! Cómo nunca probé eso nunca lo sabré.
Platinum Azure
¿Tiene algún código muerto ahí? No veo cómo el caso especial para cero es necesario cuando $ u [0] es 4. Tengo una versión aparentemente funcional de su código @ 166 caracteres, y creo que tiene espacio para ser un poco más corto que eso.
hobbs
@hobbs: Buen punto, miraré de nuevo. La historia es que llegué a la mitad de un par de revisiones y de repente las cosas se rompieron (aproximadamente en el punto en el que elegí tener 4 -> 0). Sin embargo, creo que tiene razón en este punto :-)
Platinum Azure
No me considero un gran programador de Perl, pero puedes reducir algunos caracteres: @u=split$x,'43350435543668877988';tus comas usan 19 caracteres innecesarios, dividiendo en undefdivisiones en cada carácter, uso $xcomo una variable indefinida para tomar el lugar de `undef` - total ahorro: 11 caracteres. Además, quitar el men chompy se obtiene otro personaje afeitó su puntuación.
vol7ron
Lo está haciendo mejor, pero aún puede ahorrar más si pierde por sub rcompleto: solo lo usa una vez y puede reemplazarlo todo por un solo ternario anidado sin ni siquiera parens. Mi versión es de 144 caracteres en este momento: gist.github.com/473289
hobbs
5

JavaScript 1.8 (SpiderMonkey) - 153 caracteres

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

Uso: echo 42 | js golf.js

Salida:

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

Con bonificación: 364 caracteres

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

Salida:

noventa y nueve son diez.
diez son tres.
tres son cinco.
cinco son cuatro.
cuatro es mágico.
gnarf
fuente
4

Haskell, 224 270 caracteres

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

Y poco más legible

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
Matajon
fuente
4

Versión C ++ Stdio, minificada: 196 caracteres

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

Versión C ++ Iostreams, minificada: 195 caracteres

#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";}

Original, sin minificar: 344 caracteres

#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);
}
Karl von Moor
fuente
Fijo. También lo hizo un poco más corto.
Mike DeSimone
Bien hecho. (¡Me reí mucho del enigma de los std de 20 caracteres!)
Platinum Azure
Sí, eso fue un verdadero headbanger, hasta que me di cuenta de que #definesería aún más corto ya que podría reemplazar varias fichas.
Mike DeSimone
printf("is magic".\n)=> puts. printf("%d",p)=> puts(atoi(p)). No solo más corto, sino también más rápido.
Ben Voigt
2
@Mike DeSimone: Creo que while(p!=4)podría reducirse a while(p-4). Todo un personaje, lo sé, pero aún así. :-)
Platinum Azure
3

Delphi: 329 caracteres

Versión de una sola línea:

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.

Formateado:

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.

Probablemente espacio para apretar más ... :-P

Jørn E. Angeltveit
fuente
3

C # 314 286 283 274 289 273 252 caracteres.

Aplastado:

252 

Normal:

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

Editar Dykam: Hice algunas inserciones y cambios bastante cuidadosos:

  • Se cambió l.ToString () en un molde objectde string "magic".
  • Creé una variable temporal o, por lo que podría mover el breakexterior del forbucle, es decir, dando como resultado un do-while.
  • Incluida la oasignación, así como la vasignación, continuando insertando el cálculo de len los argumentos de la función por completo, eliminando la necesidad de l. También se incluye la asignación de m.
  • Se eliminó un espacio en int[] x, también int[]xes legítimo.
  • Intenté transformar la matriz en una transformación de cadena, pero using System.Linqfue demasiado para hacer de esto una mejora.

Editar 2 Dykam Cambió la matriz int a una matriz / cadena de caracteres, agregó aritmética adecuada para corregir esto.

mdm20
fuente
Sí, lo tengo más corto que la versión de Java.
Dykam
3

Lua, 176 personajes

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."
gwell
fuente
3

C - sin palabras numéricas

180 175 * 172 167 caracteres

Todas las líneas nuevas son para facilitar la lectura y se pueden eliminar:

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

Ligeramente sin minificar:

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 versión anterior no alcanzó la marca en dos partes de la especificación: no manejó cero y tomó entrada en la línea de comando en lugar de stdin. Manejar cero caracteres agregados, pero usar stdin en lugar de argumentos de línea de comando ahorró aún más, lo que resultó en un ahorro neto.

P Papi
fuente
2

perl, 123122 caracteres

Me acabo de dar cuenta de que no hay ningún requisito para enviar a STDOUT, por lo tanto, envíe a STDERR en su lugar y elimine otro carácter.

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

Y, una versión que devuelve números detallados:

279 278 276 280 caracteres

@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/

Si bien eso cumple con las especificaciones, no está 100% bien formateado. Devuelve un espacio adicional después de los números que terminan en cero. La especificación dice:

"No me importa cómo separas las palabras tokens, aunque deberían estar separadas"

Aunque eso es una especie de comadreja. Una versión más correcta en

282 281 279 283 caracteres

@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/
user397369
fuente
1

Pitón:

#!/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"
Vlad
fuente
4
Me gusta. Sin embargo, probablemente podrías ajustarlo un poco.
Josh K
@Vlad: la entrada debe leerse de stdin en lugar de los argumentos. Eso significa que puede usar N = input()(o raw_input()) y eliminar las syscosas.
kennytm
También puede hacer que los pequeños incluyan a los adolescentes, entonces la declaración if solo sería "si n <20: devuelve los pequeños [n]". Smalls todavía funcionaría para el caso> = 20, debido al módulo en 10.
Jon Smock
5
Esta debe ser la primera vez que veo el (totalmente opcional) she-bangen una respuesta de código de golf ;-)
ChristopheD
Parece un buen comienzo ... Definitivamente ajústelo, incluso Python no necesita TODOS estos espacios en blanco. :-) Además, como señala Ferruccio, 0 no funciona, específicamente parece entrar en un bucle infinito.
Platinum Azure
1

C ++, 171 caracteres (#include omitido)

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.");}
Tom Sirgedas
fuente
Creo que si considera que esto es C, puede evitar la necesidad de #includeporque se supondrá que las funciones toman intparámetros. Incluso puede guardar un golpe haciendo una maindevolución int.
Gabe
1

Ruby, 164 caracteres

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."

descifrado:

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."
4 revoluciones
fuente
Buena solución Ruby, manteniéndolo simple. :-) (+1)
Platinum Azure
Sin embargo, mantenerlo simple no es excusa para mantenerlo demasiado largo ;-)
Joey
Creo que puede reemplazar 'if n == 0' con 'if! N'
Vincent
2
¿En Ruby? Siempre pensé que todos los valores, excepto falso y nulo, se evaluaron como verdadero :-(
Platinum Azure
1

Lua 185 190 199

puntos añadidos, io.read añadido, eliminado () en la última impresión

 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 saltos de línea

 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.'
Nick
fuente
Necesita un n=io.read()(+11 caracteres) para cumplir con la regla para leer el número de la entrada estándar. Cambiar print('4 is magic.')a print'4 is magic.'guardará 2 caracteres. Eliminar ;después )ahorrará 1 carácter. El printuso de comas parece una trampa, pero la especificación no está clara. También podría cambiarlo print(n,'is',m,'.')para guardar 2 caracteres.
gwell
¿Las comas se representan como nuevas líneas en Lua independientes? Ha pasado un tiempo desde que lo usé.
Nick Van Brunt
Las comas se representan como tabulaciones.
gwell
0

Código 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);  
}  

//////////// pruebas //////////////////

 $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';
    }

////// Resultados /////////

Twelve =6
Six =3
Three =5
Five =4
four is magic
Desarrollador
fuente
4
@wallacoloo: Una mala solución para un lenguaje malo: D
Thomas Eding
5
O 178 caracteres mucho más cortos:$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
Buen chiste. :-D Tan bien programado.
Tom Pažourek
0

Perl - 130 caracteres


5.12.1 (130 caracteres) 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 caracteres) 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/


Cambia la historia:

20100714:2223- cambio revertido a la atención de mobrule , pero ($_%10&&$u[$_%10])(($_%=10)&&$u[$_]), que es el mismo número de caracteres, pero lo hice en caso de que alguien pudiera ver una manera de mejorarlo

20100714:0041- split//,'...''...'=~/./g
20100714:0025- ($_%10&&$u[$_%10])$u[$_%10]
20100713:2340- while$_until/\D/+ se quitaron los paréntesis innecesarios
20100713:xxxx- $=<>;chop;$_=pop;- cortesía de mobrule


Nota: estaba cansado de mejorar las respuestas de los demás en los comentarios, así que ahora estoy siendo codicioso y puedo agregar mis cambios aquí :) Esta es una división de la respuesta de Platinum Azure : crédito en parte a Hobbs , mobrule y Platinum Azure .

vol7ron
fuente
Cuando se deshizo de la $_%10&&...construcción, rompió la especificación para las entradas 20,30,40, ...
mob
+1 Bien hecho. Sin embargo, ha salido de stdin a argumentos :-(
Platinum Azure
Derecha, reemplazado con ARGV, que está poblado por STDIN:) o .. echo bar | xargs perl foo.pl, técnicamente canalizado de echo a args para perl :)
vol7ron
0

Perl desvergonzado con palabras numéricas (329 caracteres)

Adaptado bastante directamente del código C de P Daddy, con algunos ajustes para p()que haga lo mismo usando primitivas de Perl en lugar de C, y un mainloop en su mayoría reescrito. Vea el suyo para una explicación. Las nuevas líneas son todas opcionales.

@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 al margen: es una lástima que Perl printsolo devuelva verdadero / falso; si devolviera una cuenta, me ahorraría 7 golpes.

hobbs
fuente
0

Ruby, 141 caracteres:

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}
Krzysztof
fuente
-7
while(true)
{
    string a;
    ReadLine(a)
    WriteLine(4);

}
usuario368038
fuente