Hay 95 caracteres ASCII imprimibles :
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
En la fuente Consolas (el bloque de código Stack Exchange predeterminado), algunos de los caracteres tienen espejos alrededor de un eje vertical de simetría:
- Estos pares de personajes son espejos el uno del otro:
()
[]
{}
<>
/\
- Estos personajes son espejos de sí mismos:
! "'*+-.8:=AHIMOTUVWXY^_ovwx|
(Tenga en cuenta que el espacio es uno). - Estos no tienen espejos:
#$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~
( i
, l
, 0
, #
, Y, probablemente, otros personajes son sus propios espejos en algunas fuentes pero me quedo con las formas Consolas).
Se dice que una cadena es un espejo de sí misma si está hecha con solo los 39 caracteres espejo , dispuestos de tal manera que la cadena tenga una línea de simetría vertical central. Entonces ](A--A)[
es un espejo de sí mismo pero ](A--A(]
no lo es.
Escriba un programa de longitud uniforme de una línea que sea un espejo de sí mismo. Cuando se le han agregado N copias de su mitad izquierda y se le han agregado N copias de su mitad derecha, debería generar N + 1. N es un entero no negativo.
Por ejemplo, si el programa era ](A--A)[
(mitad izquierda: ](A-
mitad derecha:) -A)[
, entonces:
- Correr
](A--A)[
debería dar salida1
. (N = 0) - Correr
](A-](A--A)[-A)[
debería dar salida2
. (N = 1) - Correr
](A-](A-](A--A)[-A)[-A)[
debería dar salida3
. (N = 2) - Correr
](A-](A-](A-](A--A)[-A)[-A)[-A)[
debería dar salida4
. (N = 3) - . . .
- Correr
](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[
debería dar salida10
. (N = 9) - etc.
Reglas
- Salida a stdout o la alternativa más cercana a su idioma. Puede haber una nueva línea final opcional. No se debe tomar ninguna entrada.
- El proceso debería funcionar teóricamente para N hasta 2 15 -1 o más, dada la suficiente memoria y potencia de cálculo.
- Se requiere un programa completo, no solo un comando REPL .
El programa inicial más corto (caso N = 0) en bytes gana.
fuente
#
es su propia versión, pero, tienes razón, no en consolas.Respuestas:
Pip,
1284 bytes¡Ahora con un 66% menos de bytes!
x
es una variable, preinicializada a""
. En contexto numérico, esto se convierte0
.+
, hace una expresión de la formax+x+...+x
. Esta es una declaración válida que no hace nada.+
de la primera mitad, hace una expresión de la forma++x+x+...+x
.++x
incrementax
a1
, y el resto se agrega N veces. Debido a que las expresiones se evalúan de izquierda a derecha en Pip, se garantiza que el incremento ocurra primero, y el resultado es igual al número de niveles espejo.Desafortunadamente, Pip no procesa bien grandes expresiones: esta solución causa un
maximum recursion depth exceeded
error para N por encima de 500 más o menos. Aquí hay una solución anterior que no lo hace, para 8 bytes :Más sobre Pip
fuente
Fatal error: maximum recursion depth exceeded while calling a Python object
.x+x+...+x
genera una profundidad de recursión O (N). Quizás eso invalida esta respuesta. Agregaré una nota.GolfScript, 10 bytes
Pruébelo en línea con Web Golfscript: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Web GolfScript tiene un límite de 1024 caracteres, pero el intérprete de Ruby maneja N = 32767 perfectamente:
Cómo funciona
Sin ninguna entrada, GolfScript inicialmente tiene una cadena vacía en la pila.
En la primera mitad izquierda, sucede lo siguiente:
!
aplica el NOT lógico a la cadena vacía. Esto empuja1
.:{
guarda el entero en la pila en la variable{
.Sí, ese es un identificador válido, aunque no hay forma de recuperar el valor almacenado.
)
incrementa el número entero en la pila.:
Es una instrucción incompleta.Las siguientes mitades izquierdas, sucede lo siguiente:
:!
(donde:
queda un sobrante de antes) guarda el número entero en la pila en la variable!
.Sí, eso también es un identificador válido. Esto rompe el
!
comando, pero ya no lo usamos.:{
,)
Y el:
trabajo que antes.En la primera mitad derecha, sucede lo siguiente:
::
(donde:
queda un sobrante de antes) guarda el número entero en la pila en la variable:
.Sí, incluso ese es un identificador válido. Al igual que con
{
, no hay forma de recuperar el valor almacenado.(
disminuye el número entero en la pila, produciendo el número de mitades izquierdas.}
, ya que no tiene comparación y finaliza la ejecución de inmediato.Esta es una característica no documentada. Los llamo supercomentarios .
El código restante simplemente se ignora.
fuente
}
en la segunda mitad de su código en una competencia espejo."\""/"
, la cuarta cita doble también sería inigualable ya que la segunda se ha escapado.Código máquina Z80,
86 bytes *<8ww8>
* Asume ciertas condiciones al ingresar desde Amstrad BASICA
es inicialmente 0 cuando se ingresa desde BASIC. ¡IncrementaA
n veces, luego lo escribe n veces en la misma ubicación de memoria (que BASIC establece en una ubicación ligeramente aleatoria)! losJR
operación Jump Relative nunca hace nada, ya que elC
indicador siempre está desactivado, por lo que se utiliza para "comentar" el siguiente byte. Esta versión es un poco engañosa al asumir ciertas condiciones de entrada, es decir, ingresar desde BASIC garantiza queA
siempre es 0. La ubicación de(HL)
no está garantizada como segura, y de hecho, es probablemente una ubicación peligrosa. El siguiente código es mucho más robusto, por lo que es mucho más largo.Código máquina Z80, 30 bytes
Como ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Básicamente, la primera mitad garantiza la creación de un valor cero y la segunda mitad lo incrementa y lo escribe en la memoria. En la versión ampliada a continuación, se
##
indica un código que no sirve para nada en su mitad del espejo.Desglose de las instrucciones permitidas:
De las 39 instrucciones permitidas, 28 son operaciones de carga (el bloque de 0x40 a 0x7F son
LD
instrucciones de un solo byte ), ¡la mayoría de las cuales no ayudan aquí! La única instrucción de carga en memoria aún permitida es loLD (HL), A
que significa que tengo que almacenar el valorA
. Dado queA
es el único registro que queda con un permitidoINC
instrucción , ¡esto es realmente muy útil!¡No puedo cargar
A
con 0x00 para empezar porque ASCII 0x00 no es un personaje permitido! ¡Todos los valores disponibles están lejos de 0 y todas las instrucciones matemáticas y lógicas han sido rechazadas! Excepto ... que aún puedo hacerADD HL, HL
, ¡agregar 16 bitsHL
a sí mismo! Además de cargar directamente los valores (¡no se usa aquí!), INCrementingA
y DECrementingA
,L
oHL
esta es la única forma que tengo de cambiar el valor de un registro! En realidad, hay una instrucción especializada que podría ser útil en la primera mitad, pero un trabajo difícil de resolver en la segunda mitad, y una instrucción complementaria que es casi inútil aquí y que solo ocuparía espacio.Entonces, encontré el valor más cercano a 0 que pude: 0x41. ¿Cómo es eso cerca de 0? En binario es 0x01000001. ¡Así que lo decremento, lo cargo
L
y lo hagoADD HL, HL
dos veces!L
ahora es cero, que vuelvo a cargarA
! Desafortunadamente, el código ASCIIADD HL, HL
es)
así que ahora necesito usar(
dos veces. Afortunadamente,(
esJR Z, e
, ¿dóndee
está el próximo byte? ¡Así que engulle el segundo byte y solo necesito asegurarme de que no haga nada teniendo cuidado con laZ
bandera! La última instrucción para afectar elZ
indicador fueDEC A
(contra intuitivamente,ADD HL, HL
no lo cambia) y como sé queA
era 0x40 en ese punto, está garantizado queZ
no está configurado.La primera instrucción en la segunda mitad.
JR Z, #28
no hará nada las primeras 255 veces porque el indicador Z solo se puede establecer si A se ha desbordado de 255 a 0. Después de eso, la salida será incorrecta, ya que de todos modos solo está guardando valores de 8 bits que no debería importar El código no debe expandirse más de 255 veces.El código debe ejecutarse como un fragmento, ya que se han rechazado todas las formas disponibles de regresar limpiamente. Todas las instrucciones de RETORNO están por encima de 0x80 y las pocas operaciones de salto permitidas solo pueden saltar a un desplazamiento positivo, ¡porque todos los valores negativos de 8 bits también se han rechazado!
fuente
A
registro siempre es de 8 bits, de lo contrario el procesador no sería compatible con el Z80. ¡Diría que aquí se ha cubierto suficiente memoria y potencia informática !A
registro que no sea de 8 bits? Cambiarlo a 16 bits rompería el código dependiendo de 255 + 1 = 0, por ejemplo. Tendría que inventar una CPU, llamémosla Z160, que usa un registro predeterminado de 16 bits pero aún usa el mismo conjunto de instrucciones de 8 bits del Z80. ¡Extraño!J,
1614 bytesUsos:
Explicación:
J evalúa de derecha a izquierda.
(_=_)
es loinf equals inf
que es cierto, tiene un valor de1
, por lo que la expresión se convierte1+]...[+1
. ((8=8)
También funcionaría, pero esto se ve más genial. :))[
y]
devolver sus argumentos izquierdo y derecho respectivamente si tienen 2 argumentos. Si obtienen solo 1, devuelven eso.+
agrega los 2 argumentos. Si solo obtiene 1, devuelve eso.Ahora vamos a evaluar una expresión de nivel 3 (de derecha a izquierda):
Como vemos, la mitad derecha de la
1
's se agrega y el lado izquierdo de la1
' s se omite, lo que resulta en el entero deseadoN
, el nivel del espejo.Pruébelo en línea aquí.
fuente
Haskell, 42 bytes
Afortunadamente, un comentario de línea en Haskell (->
--
) se puede reflejar y la mitad (->-
) es una función válida. El resto son algunas matemáticas para obtener los números0
y1
. Básicamente tenemos(0)-(-1)
un comentarioN=0
y un antecedente(0)-(-1)-
en cada paso.Si se permiten números de coma flotante para la salida, podemos construir
1
desde8/8
26 bytes:Haskell, 26 bytes
Salidas
1.0
,2.0
etc.fuente
program.hs
y luego ejecutarlo$ runhaskell program.hs
desde la línea de comandos y ver el resultado. No conozco a Haskell, así que no puedo decir exactamente qué necesita cambiar.runhaskell
es un script de shell que configura un entorno y finalmente llamaghc
al compilador Haskell. Puede ejecutar el código directamente conghc
:ghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"
. Esto se iniciaghc
y evalúa el código proporcionado como argumento, imprime el resultado y sale. Sin REPL, sin interacción. Por supuesto, esto agregaría +1 al recuento de bytes para-e
.-e
no contribuye a la puntuación en este caso. No contamos bytes paraperl -E
ogcc -std=c99
tampoco.CJam, 14 bytes
Pruébelo en línea en el intérprete de CJam: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Tenga en cuenta que este código termina con un mensaje de error. Usando el intérprete de Java, ese mensaje de error puede suprimirse cerrando o redirigiendo STDERR. 1
Cómo funciona
En las mitades de la izquierda, sucede lo siguiente:
]
envuelve toda la pila en una matriz.X
se une1
a esa matriz.:+
calcula la suma de todos los elementos de la matriz.Oo
imprime el contenido de una matriz vacía (es decir, nada).En la primera mitad derecha, sucede lo siguiente:
o
imprime el entero en la pila, que es el resultado deseado.O+
intenta agregar una matriz vacía al elemento superior de la pila.Sin embargo, la pila estaba vacía antes de empujar
O
. Esto falla y finaliza la ejecución del programa.El código restante simplemente se ignora.
1 De acuerdo con la meta encuesta ¿Se debe permitir que las presentaciones salgan con un error? , esto está permitido.
fuente