Salida de cadena de código de salida

18

Usted debe escribir un programa o función que, cuando se les da un no vacío cadena de S de N caracteres ASCII imprimibles , da salida a un programa que va a salir con el código de salida C , donde C es el punto de código ASCII en la posición 0 en S . Este programa se escribe lo hará, además, un programa de salida P , de tal manera que, cuando se ejecuta, se sale con código de salida C ' , donde C' es el punto de código ASCII en la posición 1 en S . El programa P generará otro programa P ' . Este proceso se repite hasta que no quedan caracteres en S. Una vez hecho esto, no debe generar nada, seguido de una nueva línea opcional; y debe salir con el código de salida 0.

Los caracteres entre 0x20e 0x7einclusive.

Algunas reglas más:

  • Los programas auto modificables no están permitidos: debe enviar la fuente a STDOUT (o, inicialmente, devolver el valor)
  • No puede leer su propio código fuente.

El programa más corto de este tipo en bytes ganará.

Para algunas pruebas rudimentarias, se puede usar este script ruby . (El primer argumento es la forma en que invocas el script, el segundo es el programa y el tercero es la cadena de entrada).

Ejemplo hipotético

Digamos que el programa es FOO. Cuando se le da la cadena "ABC", sale BARA. Este programa sale con código 65y salidas BARB. Esto a su vez sale con código 66y salidas BARC. Este programa sale con código 67y salidas BAR!. Esto no genera nada y sale con código 0.

Conor O'Brien
fuente
¿Hacer esto cuenta como códigos de salida en Forth? Cambie el parámetro para ver otros errores del sistema operativo. 0es el éxito tio.run/nexus/…
mbomb007
@ mbomb007 No sé mucho sobre Forth. ¿Es así como se usaría convencionalmente un "código de error" en Forth?
Conor O'Brien
Depende de si su objetivo es tener códigos de error a nivel del sistema operativo. Si solo importa el número, puede hacer algo como 33 throwarrojar un número arbitrario. Utiliza negativos para el nivel del sistema operativo y el desplazamiento es -512. Tampoco mucho, pero estoy buscando aquí: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Respuestas:

6

Python 2, 126 101 94 bytes

En el proceso de hacer esto, descubrí que el código Python puede no contener bytes NUL literales.

lambda i,s='''i=%r;s=%r
try:print s%%(i[1:],s,i[0])
except:0
exit(ord(%r))''':s%(i[1:],s,i[0])

Pruébelo en línea (muestra el código de salida en la información de depuración)


Tenga en cuenta que cada uno de los programas no vacíos a continuación tiene un salto de línea final.

Para la entrada Hello, las salidas anteriores:

i='ello';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('H'))

que imprime

...

que imprime

i='o';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('l'))

que imprime

i='';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('o'))

que no imprime nada (el programa vacío)

que no imprime nada y sale con el código 0.

mbomb007
fuente
4

Python 3, 77 bytes

p='exit(0)'
for c in input()[::-1]:p='print(%r);exit(ord(%r))'%(p,c)
print(p)

Este código toma la entrada de STDIN y emite el primer programa a STDOUT.

Si la entrada es ABCDE, los resultados son

 0 print('print(\'print(\\\'print("print(\\\\\\\'exit(0)\\\\\\\');exit(ord(\\\\\\\'E\\\\\\\'))");exit(ord(\\\\\\\'D\\\\\\\'))\\\');exit(ord(\\\'C\\\'))\');exit(ord(\'B\'))');exit(ord('A'))
65 print('print(\'print("print(\\\'exit(0)\\\');exit(ord(\\\'E\\\'))");exit(ord(\\\'D\\\'))\');exit(ord(\'C\'))');exit(ord('B'))
66 print('print("print(\'exit(0)\');exit(ord(\'E\'))");exit(ord(\'D\'))');exit(ord('C'))
67 print("print('exit(0)');exit(ord('E'))");exit(ord('D'))
68 print('exit(0)');exit(ord('E'))
69 exit(0)
 0 

donde cada línea contiene el código de salida y la salida del programa ejecutado previamente (la primera línea es el primer programa).

vaultah
fuente
Tu respuesta es como la mía ... solo que lo hiciste en la dirección opuesta ... Me estoy preparando para eso.
Leaky Nun
67 bytes
mbomb007
@LeakyNun, sí, pero no utilicé tu respuesta como punto de partida, si eso es lo que quieres decir
vaultah
Solo digo que debería haber pensado en eso.
Leaky Nun
@vaultah ¿Vas a jugar al tuyo con 67 bytes, o debería publicarlo como una respuesta separada?
mbomb007
3

Python 3 , 115 108 100 bytes

i=input()
r="%s"
k=""
for c in i:r%="print(%s\"%%s%s\");exit(%i)"%(k,k,ord(c));k+=k+"\\"
print(r%"")

Pruébalo en línea!


Para la entrada Hello, el programa imprime:

print("print(\"print(\\\"print(\\\\\\\"print(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\");exit(111)\\\\\\\");exit(108)\\\");exit(108)\");exit(101)");exit(72)

El programa anterior imprime:

print("print(\"print(\\\"print(\\\\\\\"\\\\\\\");exit(111)\\\");exit(108)\");exit(108)");exit(101)

y sale con código 72.

Pruébalo en línea!


El programa anterior imprime

print("print(\"print(\\\"\\\");exit(111)\");exit(108)");exit(108)

y sale con código 101.

Pruébalo en línea!


El programa anterior imprime:

print("print(\"\");exit(111)");exit(108)

y sale con código 108.

Pruébalo en línea!


El programa anterior imprime:

print("");exit(111)

y sale con código 108.

Pruébalo en línea!


El programa anterior no imprime nada y sale con código 111.

Pruébalo en línea!


El programa vacío no imprime nada y sale con código 0.

Pruébalo en línea!

Monja permeable
fuente
2
¿Un enlace TIO para el programa vacío? ¡Eso es dedicación para ti!
Neil
2

C, 156 bytes

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";main(i,t)char**t;{printf(s,34,s,34,0,34,t[1],34);}

Pruébalo en línea! (Abra la pestaña de depuración para ver el código de salida).

Toma la entrada como un argumento de línea de comando.

Para la entrada "ABC", esto genera el programa

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=0;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

que devuelve 65 y produce

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=1;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

que devuelve 66 y produce

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=2;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

que devuelve 67 y produce

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=3;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

que no genera nada y devuelve 0.

Steadybox
fuente
@ mbomb007 Gracias, ahora está arreglado (y se acortó en el proceso).
Steadybox
2
Debo amarlo cuando eso suceda.
mbomb007
2

Python 2, 67 bytes

Basado en esta respuesta , pero modificado para usar Python 2, con un programa trivial 0para imprimir nada y salir.

p=0
for c in input()[::-1]:p='print %r;exit(ord(%r))'%(p,c)
print p

Pruébalo en línea

mbomb007
fuente
1

RPL, 73 bytes

Con la página de códigos hp8.

Encienda su HP48 o similar, o dispare droid48 . No te olvides de -52 SFuna mejor visualización de la pila. Supongo que ya ha empujado la cadena, por ejemplo "ABC", en la pila. Luego ingrese la siguiente función:

→ x«{LAST}x{DUP NUM 3ROLLD 2OVER SIZE DUP{SUB 2SWAP PUT}{4DROPN}IFTE}+ +»

(Por conveniencia, sugiero presionar la tecla α dos veces antes de escribir cualquier cosa, por lo tanto, bloquear el modo de entrada alfa. Posteriormente use la tecla DEL para cancelar los delimitadores de cierre insertados automáticamente. Simplemente use la tecla ENTER para validar. No olvide el espacio después del operador de puñalada.)

Esta función empuja inmediatamente en la pila un programa auto modificable, bajo la forma de una lista. (Pero la función anterior no se modifica a sí misma). Como L en RPL originalmente significa LISP, presionar la tecla EVAL evaluará este programa. Devuelve el código de salida en el nivel dos de la pila y se deja modificado (sí, aquí es cuestionable), para un último EVAL. Por lo tanto, presione EVAL varias veces hasta que el programa finalmente se detenga para caer en el nivel uno de la pila. El código de salida final 0 aparece así en el nivel uno, con los códigos de salida anteriores arriba. Si olvidó hacerlo -52 SF, puede navegar en la pila después de cada EVAL presionando la tecla ▴ (salga de este modo de navegación con la tecla ON). La función anterior acepta cadenas con caracteres 0x0 dentro, para crear tales cadenas0 CHR y+son tus amigos. La auto modificación consiste en eliminar el char usado de la cadena incrustada (la SUB 2 SWAP PUTrama). Por lo tanto, el programa eliminado es más corto después de cada EVAL. La 4 DROPNrama asegura que la salida no respeta las instrucciones del OP, eliminando entre otros el programa en sí. Por supuesto, todo esto supone que su nota es -55 SFexperta. Los usuarios de -55 SFserán prohibidos. Siempre.

Supongo que existe una solución RPL / 2, y podría presentar un código de salida de Unix real, pero afaik RPL / 2 tiene una introspección limitada y no puede evaluar listas.

Nácar
fuente
No creo que el uso de código de auto-modificación cuente como un quine válido de acuerdo con nuestro consenso, ya que tiene acceso a su propio código fuente. Le preguntaré al OP en un comentario. Ver meta publicaciones relacionadas: ¿Qué cuenta como una quine adecuada? ; ¿El uso de SMBF cuenta como una trampa engañosa? <- este es el que aplica
mbomb007
1
Solo el programa generado se modifica a sí mismo, no la función que responde al desafío. Pero estoy de acuerdo, ¡esto es cuestionable! Se agregaron algunas ediciones para resaltar esto.
Nácar
1

sed , 467 461 bytes

Los códigos de caracteres son difíciles:

s:^:Y:
:b
s:ZY[ (2<FPZdnx]:0_Y:
s:ZY[ )3=GQ[eoy]:1_Y:
s:ZY[ *4>HR\fpz]:2_Y:
s:ZY[]!+5?ISgq{]:3_Y:
s:ZY[",6@JT^hr|]:4_Y:
s:ZY[-#7AKU_is}]:5_Y:
s:ZY[$.8BLV`jt~]:6_Y:
s:ZY[%/9CMWaku]:7_Y:
s:ZY[&0:DNXblv]:8_Y:
s:ZY['1;EOYcmw]:9_Y:
s:Y[ -']:3Z&:
s:Y[(-1]:4Z&:
s:Y[2-9:;]:5Z&:
s:Y[<=>?@A-E]:6Z&:
s:Y[F-O]:7Z&:
s:Y[P-Y]:8Z&:
s:Y[]Z\-`abc]:9Z&:
s:Y[d-m]:10Z&:
s:Y[n-w]:11Z&:
s:Y[xyz{-~]:12Z&:
tb
s/([^_]+)_Y$/ q\1/
:
s/[/\]/\\&/g
s/([^_]+)_ (.*)/ s\/^\/\2\/;q\1/
/^\S/b

Pruébalo en línea!

De lo contrario, la lógica es bastante sencilla: (1) escapar caracteres especiales (hay dos), (2) envolver en una s/^/…/;q\1capa adicional , (3) repetir.

Aquí está la salida para hello:

 s/^/s\/^\/s\\\/^\\\/s\\\\\\\/^\\\\\\\/q111\\\\\\\/;q108\\\/;q108\/;q101/;q104

Y un pequeño script que usé:

#!/bin/bash
set -uo pipefail
IFS=$'\n'

P=$(echo $1 | sed -rf q.sed)
echo $P

echo $1 | od -An -tuC

for char in $(echo $1 | sed 's:.:&\n:g'); do
    P=$(echo | sed $P)
    printf ' %3d' $?
done
eush77
fuente
No necesita preocuparse por las nuevas líneas, ya que la publicación dice que solo se le darán caracteres entre 0x20 y 0x7E. Buena solución! :)
Conor O'Brien
@ ConorO'Brien Oh, cierto. ¡Gracias!
eush77
1

PowerShell, 172156 bytes.

param($i)
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f$i.replace("'","''"),"$s`n"

La h3l}'{l0entrada dará como resultado la próxima salida

Pruébalo en línea!

if($i='h3l}''{l0'){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit

Que a su vez dará salida

Pruébalo en línea!

if($i='3l}''{l0'){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit

La última ejecución no generará nada y el código de salida será 0.

Pruébalo en línea!

if($i=''){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit
Andrei Odegov
fuente