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:
- Las soluciones deben ser programas completos en sí mismos. No pueden ser simplemente funciones que incorporan un factor numérico en la entrada.
- 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)
- La entrada debe estar en forma numérica.
- 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.
- ¡Se requieren paradas completas (puntos)!
- La última línea debería decir naturalmente, 4 is magic..
- 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:
- Quiero que la palabra aparezca en ambos lados en todos los casos aplicables, p. Ej. Nine is four. Four is magic.
- 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.
fuente

Respuestas:
GolfScript -
10196939291909486 bytes90 → 94: Salida fija para múltiplos de 1094 → 86.: Código reestructurado. Usando base 100 para eliminar caracteres no imprimibles.86 → 85: Lanzamiento más corto a la cuerda.fuente
"magic.", lo resume bastante bien.des extraído por el)as100y se usa como base para la conversión base.Perl, aproximadamente 147 caracteres
Basado libremente en la solución de Platinum Azure:
fuente
pop, sin ningún argumento. Fuera de una subrutinapop, elimina y devuelve el último valor del@ARGVcual es la lista de argumentos al programa Perl. Podría reemplazarse fácilmente conshift, pero eso agrega otros 2 caracteres. Ver: p3rl.org/pop'.', que es 2 para\no 1 si está contando espacios en blanco en el'. '(el espacio es el literal de nueva línea)Common Lisp 157 caracteres
Nueva versión más conforme, ahora leyendo la entrada estándar de forma e ignorando espacios y guiones:
En forma legible por humanos:
Y algunas pruebas se ejecutan:
Y la versión adicional, con 165 caracteres:
Dando
fuente
Python 2.x, 144
150154166caracteresEsto 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 cquecse devuelve sibes 0.La versión ingenua anterior (150 caracteres). Simplemente codifique todas las longitudes como un número entero.
fuente
n,"is",p,"."? Creo que todavía guardas algunos personajes si estoy contando bien)..int(), decir algo fuera de los módulosstructobase64...C - con palabras numéricas
445431427421399386371359 *356354 †348347 caracteresEso es. No creo que pueda hacer esto más corto.
Todas las líneas nuevas son para facilitar la lectura y se pueden eliminar:
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.
Ampliado y comentado:
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. Laprint()función genera los caractereseyl(minúscula 'L', no el número '1') literalmente, pero luego encuentra elM, 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 esevL, por lo que generaeyv, luego, se vuelve a llamar a sí misma con el índice de la entrada 28 en la tabla de búsqueda, que eseny es salida textualmente. Esto es útil porqueentambién se usa eneLforeen(usado después deeightineighteen), que se usa entOforteen(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
#includeAlgunos 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 regresandoint, 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:
* 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.
fuente
J, 107
112caracteres(Nueva línea solo para facilitar la lectura)
Uso y salida:
fuente
T-SQL, 413
451499caracteres(No es que esté sugiriendo seriamente que hagas esto ... realmente solo quería escribir un CTE)
Usar:
Devoluciones
fuente
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)ENDJava (con repetitivo),
308290286282280 caracteresEstoy 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
Editar: Ya no use hexadecimal, esto es menos pulsaciones de teclas
fuente
String[]alugar deString[] a.Windows PowerShell: 152
153184bytesbasado en la solución anterior, con más influencia de otras soluciones
fuente
$inputdeben permanecer ya que no puede enviar un enumerador directamente aint; funciona cuando se pasastringprimero :-)C, 158 caracteres
(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:
fuente
Pitón, 129
133137148caracteresComo 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:
fuente
C #: 210 caracteres.
Aplastado:
Expandido:
Trucos que utiliza este enfoque:
Console.aC.?:) en lugar deif/else.\ncon elWritecódigo de escape en lugar deWriteLineWritellamada a funciónfuente
int[] zsería más corto ya que no necesita elnew[]"magic"aobject, sería implícitamente llamarToString()enyañ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".Perl: 148 caracteres
(Perl:
233181212206200199198185179149148 caracteres)res innecesaria, se ha reducido un poco más.Hagamos rodar esta bola con un modesto intento en Perl.
Trucos:
¡Demasiados!
fuente
@u=split$x,'43350435543668877988';tus comas usan 19 caracteres innecesarios, dividiendo enundefdivisiones en cada carácter, uso$xcomo una variable indefinida para tomar el lugar de `undef` - total ahorro: 11 caracteres. Además, quitar elmenchompy se obtiene otro personaje afeitó su puntuación.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/473289JavaScript 1.8 (SpiderMonkey) - 153 caracteres
Uso:
echo 42 | js golf.jsSalida:
Con bonificación: 364 caracteres
Salida:
fuente
Haskell, 224
270caracteresY poco más legible
fuente
Versión C ++ Stdio, minificada: 196 caracteres
Versión C ++ Iostreams, minificada: 195 caracteres
Original, sin minificar: 344 caracteres
fuente
#definesería aún más corto ya que podría reemplazar varias fichas.printf("is magic".\n)=>puts.printf("%d",p)=>puts(atoi(p)). No solo más corto, sino también más rápido.while(p!=4)podría reducirse awhile(p-4). Todo un personaje, lo sé, pero aún así. :-)Delphi: 329 caracteres
Versión de una sola línea:
Formateado:
Probablemente espacio para apretar más ... :-P
fuente
C #
314286283274289273252 caracteres.Aplastado:
Normal:
Editar Dykam: Hice algunas inserciones y cambios bastante cuidadosos:
objectdestring"magic".o, por lo que podría mover elbreakexterior delforbucle, es decir, dando como resultado undo-while.oasignación, así como lavasignación, continuando insertando el cálculo delen los argumentos de la función por completo, eliminando la necesidad del. También se incluye la asignación dem.int[] x, tambiénint[]xes legítimo.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.
fuente
Lua, 176 personajes
o
fuente
C - sin palabras numéricas
180175*172167 caracteresTodas las líneas nuevas son para facilitar la lectura y se pueden eliminar:
Ligeramente sin minificar:
* 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.
fuente
perl,
123122caracteresMe 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.
Y, una versión que devuelve números detallados:
279278276280 caracteresSi 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:
Aunque eso es una especie de comadreja. Una versión más correcta en
282281279283 caracteresfuente
Pitón:
fuente
N = input()(oraw_input()) y eliminar lassyscosas.she-bangen una respuesta de código de golf ;-)C ++, 171 caracteres (#include omitido)
fuente
#includeporque se supondrá que las funciones tomanintparámetros. Incluso puede guardar un golpe haciendo unamaindevoluciónint.Ruby, 164 caracteres
descifrado:
fuente
Lua
185190199puntos añadidos, io.read añadido, eliminado () en la última impresión
con saltos de línea
fuente
n=io.read()(+11 caracteres) para cumplir con la regla para leer el número de la entrada estándar. Cambiarprint('4 is magic.')aprint'4 is magic.'guardará 2 caracteres. Eliminar;después)ahorrará 1 carácter. Elprintuso de comas parece una trampa, pero la especificación no está clara. También podría cambiarloprint(n,'is',m,'.')para guardar 2 caracteres.Código PhP
//////////// pruebas //////////////////
////// Resultados /////////
fuente
$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";Perl - 130 caracteres
5.12.1 (130 caracteres)
1211231321361405.10.1 (134 caracteres)
125127136140144Cambia 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 mejorarlo20100714:0041-split//,'...'→'...'=~/./g20100714:0025-($_%10&&$u[$_%10])→$u[$_%10]20100713:2340-while$_→until/\D/+ se quitaron los paréntesis innecesarios20100713:xxxx-$=<>;chop;→$_=pop;- cortesía de mobruleNota: 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 .
fuente
$_%10&&...construcción, rompió la especificación para las entradas 20,30,40, ...ARGV, que está poblado porSTDIN:) o ..echo bar | xargs perl foo.pl, técnicamente canalizado de echo a args para perl :)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.Nota al margen: es una lástima que Perl
printsolo devuelva verdadero / falso; si devolviera una cuenta, me ahorraría 7 golpes.fuente
Ruby, 141 caracteres:
fuente
fuente