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-nine
está bien,ninety nine
está bien,ninetynine
no 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.d
es extraído por el)
as100
y 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@ARGV
cual 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\n
o 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 c
quec
se devuelve sib
es 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ódulosstruct
obase64
...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 caracterese
yl
(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 generae
yv
, luego, se vuelve a llamar a sí misma con el índice de la entrada 28 en la tabla de búsqueda, que esen
y es salida textualmente. Esto es útil porqueen
también se usa eneL
foreen
(usado después deeight
ineighteen
), que se usa entO
forteen
(usado para cualquier otro-teen
nombre).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()
argv
se 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 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)END
Java (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[]a
lugar deString[] a
.Windows PowerShell: 152
153184bytesbasado en la solución anterior, con más influencia de otras soluciones
fuente
$input
deben permanecer ya que no puede enviar un enumerador directamente aint
; funciona cuando se pasastring
primero :-)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
.\n
con elWrite
código de escape en lugar deWriteLine
Write
llamada a funciónfuente
int[] z
sería más corto ya que no necesita elnew[]
"magic"
aobject
, sería implícitamente llamarToString()
eny
añ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)r
es 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 enundef
divisiones en cada carácter, uso$x
como una variable indefinida para tomar el lugar de `undef` - total ahorro: 11 caracteres. Además, quitar elm
enchomp
y se obtiene otro personaje afeitó su puntuación.sub r
completo: 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.js
Salida:
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
#define
serí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:
object
destring
"magic"
.o
, por lo que podría mover elbreak
exterior delfor
bucle, es decir, dando como resultado undo-while
.o
asignación, así como lav
asignación, continuando insertando el cálculo del
en los argumentos de la función por completo, eliminando la necesidad del
. También se incluye la asignación dem
.int[] x
, tambiénint[]x
es legítimo.using System.Linq
fue 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 lassys
cosas.she-bang
en una respuesta de código de golf ;-)C ++, 171 caracteres (#include omitido)
fuente
#include
porque se supondrá que las funciones tomanint
parámetros. Incluso puede guardar un golpe haciendo unamain
devolució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. Elprint
uso 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//,'...'
→'...'=~/./g
20100714: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
print
solo devuelva verdadero / falso; si devolviera una cuenta, me ahorraría 7 golpes.fuente
Ruby, 141 caracteres:
fuente
fuente