Escribir un programa que sea válido después del cambio de carácter circular.

17

Potencialmente muy difícil, pero he visto algunas cosas increíbles que salen de este sitio.

El objetivo es escribir un programa, en cualquier idioma, que haga lo que quiera. El problema es que el programa debe ser válido después de cualquier desplazamiento circular de los caracteres.

Un cambio de carácter circular es muy similar a un cambio circular . Algunos ejemplos aclaran mis cosas.

Para el programa int main() { return 0; }

El desplazamiento hacia la izquierda por 6 caracteres produce: in() { return 0; }int ma

desplazarse a la izquierda por 1 carácter produce: nt main() { return 0; }i

desplazarse a la derecha por 10 caracteres produce: eturn 0; }int main() { r

Sin embargo, este programa obviamente no cumple con las reglas.

Reglas

  • Cualquier idioma
  • El ganador se decide por recuento de votos
  • Las soluciones que hacen lo mismo, o cosas completamente diferentes para cada rotación, recibirán 100 votos virtuales para su puntaje.

ACTUALIZACIÓN Creo que esto ha durado lo suficiente. El ganador, con más votos (votos virtuales incluidos) es Mark Byers. ¡Bien hecho!

Grifo
fuente
55
Hay algunas respuestas potenciales muy aburridas en los idiomas en los que un literal literal es un programa válido. ¿Reciben un virtual -100?
Peter Taylor
1
@ PeterTaylor Supongo que las respuestas aburridas recibirán menos votos.
Griffin
"Potencialmente muy difícil" Siempre es útil estar familiarizado con muchos idiomas extraños antes de hacer este tipo de declaración de manera general. Difícil en c o java, claro, pero en idiomas con comandos de 1 carácter y sintaxis simples. No tanto.
dmckee
@dmckee de ahí el "Potencialmente" ...
Griffin
@PeterTaylor también en muchos idiomas, el programa vacío es un programa válido
jk.

Respuestas:

31

Use el lenguaje correcto para la tarea. En este caso, ese es Befunge .

Este lenguaje permite naturalmente rotaciones porque:

  • Todos los comandos son un solo personaje.
  • El control se envuelve cuando llega al final del programa, comenzando nuevamente desde el principio.

Este programa Befunge imprime exactamente la misma salida ("Hola") independientemente de cuántos "cambios de caracteres circulares" utilice:

86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p645**2-00p645**2-00p

Se ejecuta en Befungee . Requiere que se aumente el tablero (no el valor predeterminado de 80 caracteres). Se puede ejecutar así:

python befungee.py -w400 hello.bef

Funciona primero generando y almacenando dinámicamente un programa que imprime "Hola" y luego sobrescribiendo el primer byte para redirigir el control al programa recién escrito. El programa se escribe dos veces, de modo que si un byte no se escribe correctamente la primera vez, se corregirá la segunda vez.

La idea podría extenderse para producir cualquier programa de complejidad arbitraria.

Mark Byers
fuente
Muy buena entrada!
ChristopheD
22

Brainf * ck

Elija la herramienta adecuada para el trabajo: ¡un adagio que nunca ha sido más relevante que este trabajo aquí mismo!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.+.>++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.++++++++++++++.>++++++++++.+

El programa no desplazado que ve aquí simplemente se imprime SHIFT(más una nueva línea). Los cambios circulares de forma abrupta producirán varias otras salidas, aunque siempre generarán seis caracteres ASCII.

caja de pan
fuente
Leí la pregunta y pensé, Brainfuck, ese es el boleto, pero me ganaste.
jmoreno
12

Commodore 64 BÁSICO

?es la abreviatura de PRINTy :es un separador de sentencias, entonces:

?1:?2:?3:          // prints 1, 2, and 3
:?1:?2:?3          // prints 1, 2, and 3
3:?1:?2:?          // adds a program line 3 :PRINT1:PRINT2:PRINT
?3:?1:?2:          // prints 3, 1, and 2
:?3:?1:?2          // prints 3, 1, and 2
2:?3:?1:?          // adds a program line 2 :PRINT3:PRINT1:PRINT
?2:?3:?1:          // prints 2, 3, and 1
:?2:?3:?1          // prints 2, 3, and 1
1:?2:?3:?          // adds a program line 1 :PRINT2:PRINT3:PRINT

Las variaciones más largas son, por supuesto, posibles:

?1:?2:?3:?4:?5:?6:?7:?8:?9:?10:?11:

etc ...

Danko Durbić
fuente
11

Golfscript

Este programa imprime algunos dígitos que siempre suman 2, independientemente de cómo se cambie el programa:

10 2 base
0 2 base1
 2 base10
2 base10 
 base10 2
base10 2 
ase10 2 b
se10 2 ba
e10 2 bas

Se imprime la primera línea 1010(10 en binario), se imprime la segunda línea 02y se imprimen todas las demás líneas2 .

Actualizar:

El programa se puede probar aquí . Tenga en cuenta que he agregado ns al final de cada fila solo para formatear la salida; estos se pueden eliminar y el programa aún funciona.

Cristian Lupascu
fuente
10

Ruby, probablemente una de las soluciones más cortas posibles:

p

Y otro un poco más largo y más interesante:

;;p";p;";p
Jon
fuente
9

binario x86 de 16 bits

Construido manualmente con la ayuda de estas ( 1 2 ) tablas, nasm y ndisasm. Esto siempre regresará sin un bloqueo o bucle infinito, porque no hay bytes que salten o cambien la pila y se llene con NOP para terminar con un solo byteret instrucción de en cualquier caso.

En la mayoría de los casos, esto generará FOO una subcadena de eso. Si AXestá roto, esto llamará un int 10 aleatorio (esto cambió la velocidad de parpadeo del cursor en una de mis pruebas), pero generalmente no resulta en un bloqueo.

Para probar, coloque el hexdump en un archivo y use xxd -r foo.hex > foo.com , luego ejecútelo en un entorno de dos (usé dosbox).

Aquí hay un volcado hexadecimal de este archivo:

0000000: b846 0d90 90fe c490 9090 bb05 0090 9043  .F.............C
0000010: 43cd 1090 b84f 0d90 90fe c490 9090 bb05  C....O..........
0000020: 0090 9043 43cd 1090 b84f 0d90 90fe c490  ...CC....O......
0000030: 9090 bb05 0090 9043 43cd 1090 9090 c3    .......CC......

Y algunas compensaciones interesantes desmontadas:

+0

00000000  B8420D            mov ax,0xd42
00000003  90                nop
00000004  90                nop
00000005  FEC4              inc ah
00000007  90                nop
00000008  90                nop
00000009  90                nop
0000000A  BB0500            mov bx,0x5
0000000D  90                nop
0000000E  90                nop
0000000F  43                inc bx
00000010  43                inc bx
00000011  CD10              int 0x10
00000013  90                nop
00000014  B84F0D            mov ax,0xd4f
00000017  90                nop
00000018  90                nop
00000019  FEC4              inc ah
0000001B  90                nop
0000001C  90                nop
0000001D  90                nop
0000001E  BB0500            mov bx,0x5
00000021  90                nop
00000022  90                nop
00000023  43                inc bx
00000024  43                inc bx
00000025  CD10              int 0x10
00000027  90                nop
00000028  B84F0D            mov ax,0xd4f
0000002B  90                nop
0000002C  90                nop
0000002D  FEC4              inc ah
0000002F  90                nop
00000030  90                nop 
00000031  90                nop
00000032  BB0500            mov bx,0x5
00000035  90                nop
00000036  90                nop
00000037  43                inc bx
00000038  43                inc bx
00000039  CD10              int 0x10
0000003B  90                nop
0000003C  90                nop
0000003D  90                nop
0000003E  C3                ret

(para los ejemplos a continuación, el resto del binario sigue siendo válido)

+1

00000000  42                inc dx
00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+2

00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+6

00000000  C4909090          les dx,[bx+si-0x6f70]
00000004  BB0500            mov bx,0x5
00000007  90                nop
00000008  90                nop
00000009  43                inc bx
0000000A  43                inc bx
0000000B  CD10              int 0x10

+11

00000000  050090            add ax,0x9000
00000003  90                nop
00000004  43                inc bx
00000005  43                inc bx
00000006  CD10              int 0x10

+12

00000000  00909043          add [bx+si+0x4390],dl
00000004  43                inc bx
00000005  CD10              int 0x10

+18

00000000  1090B84F          adc [bx+si+0x4fb8],dl
00000004  0D9090            or ax,0x9090
00000007  FEC4              inc ah
00000009  90                nop

(otras compensaciones son solo repeticiones de lo anterior)

+58

00000000  10909090          adc [bx+si-0x6f70],dl
00000004  C3                ret
Copiar
fuente
7

Respuesta unaria:

000000 ... 00000

^ 44391 Ceros

Programa de gatos. No importa cómo rotas, es el mismo programa.

Walpen
fuente
6

PHP

Aquí tienes, un programa PHP válido:

Is this still funny?
un tipo triste
fuente
2
deberías haber usado una palabra como "comió" (estoy seguro de que hay otras más largas), para que cada cambio de caracteres siga siendo una palabra real.
Peter
10
No estoy seguro de si hacer +1 en esto o -1 en esto
Lie Ryan
6

Scala

A citas anidadas:

""""""""""""""""""""""""""""""""

C ++ / Java / C # / Scala

Comentario:

///////////////////////////////////

Comando vacío:

;;;;;;;;;;;;;;;

Golpetazo

Comentario, combinación de espacios en blanco y Shell:

#

:

Sed

Comandos válidos independientes:

p P n N g G d D h H

Una combinación de lo anterior:

p;P;n;N;g;G;d;D;h;H;

AWK

Para imprimir cada línea del archivo:

1

o

//

No imprimas nada:

0

Perl

abcd
Príncipe John Wesley
fuente
¿Me parece que SED fallaría en cualquier rotación impar? Es ;P;n;N;g;G;d;D;h;Hvalido?
captncraig
@CMP: sí, es válido.
Príncipe John Wesley
5

J

Primero, un script para verificar rotaciones válidas de un programa s:

check =: 3 :'((<;(". :: (''Err''"_)))@:(y |.~]))"0 i.#y'

Por ejemplo, el programa +/1 5(suma de 1 y 5) da:

 check '+/1 5'
┌───────┬───┐
│┌─────┐│6  │
││+/1 5││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││/1 5+││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││1 5+/││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││ 5+/1││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││5+/1 ││   │
│└─────┘│   │
└───────┴───┘

Luego, un programa aburrido y válido:

check '1x1'
┌─────┬───────┐
│┌───┐│2.71828│ NB. e^1
││1x1││       │
│└───┘│       │
├─────┼───────┤
│┌───┐│       │ NB. Value of variable x11
││x11││       │ 
│└───┘│       │
├─────┼───────┤
│┌───┐│11     │ NB. Arbitrary precision integer
││11x││       │
│└───┘│       │
└─────┴───────┘
Eelvex
fuente
2

corriente continua

Los programas de CC son fácilmente válidos en cualquier rotación. Por ejemplo:

4 8 * 2 + p  # 34
8 * 2 + p 4  # stack empty / 10
...
Eelvex
fuente
1

Codigo de maquina

¿Qué hay del código de máquina Z80 / Intel 8051 para NOP ?

Claro que no hace ninguna operación, pero toma un ciclo o dos ... puede tener tantos o tan pocos como desee.

Y no estoy de acuerdo con la respuesta de Ruby anterior: creo que un solo byte 00h es más corto que un Ruby p.

Richard Le Mesurier
fuente
1

k

.""

Evalúa una cadena vacía

"."

Devuelve un carácter de punto

"".

Devuelve la aplicación parcial de '.' (forma dinámica) a una lista de caracteres vacía.

skeevey
fuente
1

sh, bash

cc
cc: no input files

cc girado es cc nuevamente, pero no es muy amigable si se llama tan desnudo.

dh 
dh: cannot read debian/control: No such file or directory
hd 

dh debhelper tampoco es muy cooperativo, mientras que hexdump solo espera la entrada.

gs
sg 

Ghostscript inicia el modo interactivo, mientras que el grupo de conmutadores muestra un mensaje de uso, una solución válida aquí, en mi opinión, también.

Y aquí está el guión para encontrar candidatos para tales programas:

#!/bin/bash
for name in /sbin/* /usr/sbin/* /bin/* /usr/bin/*
do 
    len=${#name}
    # len=3 => 1:2 0:1, 2:1 0:2
    # len=4 => 1:3 0:1, 2:2 0:2, 3:1 0:3
    for n in $(seq 1 $((len-1)))
    do
        init=${name:n:len-n}
        rest=${name:0:n}
        # echo $init$rest
        which /usr/bin/$init$rest 2>/dev/null >/dev/null && echo $name $init$rest $n
    done 
done

Si también encuentra secuencias más largas, como (arj, jar) o (luatex, texlua) que no son válidas después de cada turno, pero solo después de ciertos turnos, que leí mal al principio, pero hay pocos, por lo que es fácil para filtrarlos a mano.

usuario desconocido
fuente
Los ejemplos de más de dos letras no son válidos; el OP dijo que "el programa debe ser válido después de cualquier turno circular". Entonces, arj/ jarno es válido, ya que no hay un rjacomando (aunque me gusta este ejemplo). +1 para el guión: muy buena idea :)
Cristian Lupascu
Como no estaba seguro, y no era un hablante nativo de inglés, consulté un diccionario, donde lo encontré ambiguo, ya sea para querer decir everyo para querer decir a random one. El ejemplo con shift left by 6, left by 1y right by 10me aseguró en la interpretación, que solo necesito encontrar una sola posibilidad de cambio.
usuario desconocido
No es ambiguo. Si un programa tiene que ser válido después de un turno aleatorio, entonces también debe ser válido para cada turno posible.
Griffin
@Griffin: Ok, escribiste la pregunta. Eliminé los ejemplos más largos; afortunadamente, hay suficientes crptc abbrv prgnms en unix como gs y sg. :) Por cierto .: ¿Eres un hablante nativo de inglés? En la oración anterior, escribió ... in any language ... : mi solución solo funciona en bash (y sh, zsh, ash y algunas otras), pero todas esas otras soluciones también toman nombres de programas.
usuario desconocido
0

Ejemplo trivial de Python:

"a""b""c""d""e""f""g""h""i""j""k""l""m""n""o""p""q""r""s""t""u""v""w""x""y""z""";print

Se pueden cambiar tres caracteres repetidamente para revelar más y más del alfabeto.

Walpen
fuente
Lo siento, debería haber aclarado mi pregunta. Cualquier turno debe producir un programa válido. He actualizado la pregunta.
Griffin
0

Pitón

123456789.0

Solo evalúa algunos números

MrD
fuente
0

dc ya se usa, pero el siguiente programa siempre genera lo mismo , sin importar la rotación: D

d

salidas

dc: stack empty
daniero
fuente