Saída da sequência do código de saída

18

Você deve escrever um programa ou função que, quando é dada uma nonempty seqüência S de N caracteres ASCII imprimíveis , gera um programa que vai sair com código de saída C , onde C é o codepoint ASCII na posição 0 em S . Este programa que você escreve, adicionalmente, a saída de um programa de P , de tal forma que, quando executado, ele sai com código de saída C " , onde C ' é o ponto de código ASCII na posição 1 em S . O programa P produzirá outro programa P ' . Esse processo se repete até que não haja mais caracteres em S. Depois disso, você não deve produzir nada, seguido por uma nova linha opcional; e deve sair com o código de saída 0.

Os caracteres entre 0x20e 0x7einclusive.

Mais algumas regras:

  • Programas de modificação automática não são permitidos: você deve enviar a fonte para STDOUT (ou, retornar o valor inicialmente)
  • Você não pode ler seu próprio código-fonte.

O menor programa desse tipo em bytes vencerá.

Para alguns testes rudimentares, esse script ruby pode ser usado. (O primeiro argumento é a maneira como você invoca o script, o segundo é o programa e o terceiro é a sequência de entrada.)

Exemplo hipotético

Digamos que o programa seja FOO. Quando recebe a string "ABC", ela gera BARA. Este programa sai com código 65e saídas BARB. Por sua vez, sai com código 66e saídas BARC. Este programa sai com código 67e saídas BAR!. Isso não gera nada e sai com o código 0.

Conor O'Brien
fonte
Fazer isso conta como códigos de saída em Forth? Altere o parâmetro para ver outros erros do SO. 0é sucesso. tio.run/nexus/…
mbomb007 10/10
@ mbomb007 Não sei muito sobre a Forth. É assim que alguém usaria convencionalmente um "código de erro" em Forth?
Conor O'Brien
Depende se seu objetivo é ter códigos de erro no nível do sistema operacional. Se apenas o número importa, você pode fazer algo como 33 throwlançar um número arbitrário. Você usa negativos para o nível do sistema operacional e o deslocamento é -512. Idk muito quer, mas eu estou olhando aqui: complang.tuwien.ac.at/forth/gforth/Docs-html/...
mbomb007

Respostas:

6

Python 2, 126 101 94 bytes

No processo de fazer isso, descobri que o código Python pode não conter bytes NUL literais.

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])

Experimente online (mostra o código de saída nas informações de depuração)


Observe que cada um dos programas não vazios abaixo possui um avanço de linha à direita.

Para entrada Hello, as saídas acima:

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 não imprime nada (o programa vazio)

que imprime nada e sai com o código 0.

mbomb007
fonte
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 recebe a entrada de STDIN e envia o primeiro programa para STDOUT.

Se a entrada for ABCDE, os resultados serão

 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 

onde cada linha contém o código de saída e a saída do programa executado anteriormente (a primeira linha é o primeiro programa).

vaultah
fonte
Sua resposta é como a minha ... só que você fez isso na direção oposta ... estou me enfrentando por isso.
Leaky Nun
67 bytes
mbomb007
@LeakyNun sim, mas eu não usar a sua resposta como um ponto de partida, se é isso que você quer dizer
vaultah
Só estou dizendo que deveria ter pensado nisso.
Leaky Nun
@vaultah Você vai jogar o seu com 67 bytes, ou devo publicá-lo como uma resposta 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%"")

Experimente online!


Para a entrada Hello, o programa imprime:

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

O programa acima imprime:

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

e sai com o código 72.

Experimente online!


O programa acima imprime

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

e sai com o código 101.

Experimente online!


O programa acima imprime:

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

e sai com o código 108.

Experimente online!


O programa acima imprime:

print("");exit(111)

e sai com o código 108.

Experimente online!


O programa acima imprime nada e sai com o código 111.

Experimente online!


O programa vazio imprime nada e sai com o código 0.

Experimente online!

Freira Furada
fonte
2
Um link TIO para o programa vazio? Isso é dedicação para você!
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);}

Experimente online! (Abra a guia de depuração para ver o código de saída.)

Recebe entrada como um argumento de linha de comando.

Para a entrada "ABC", isso gera o 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 retorna 65 e produz

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 retorna 66 e produz

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 retorna 67 e produz

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 não gera nada e retorna 0.

Steadybox
fonte
@ mbomb007 Obrigado, está consertado agora (e ficou mais curto no processo).
Steadybox #
2
Tenho que amar quando isso acontece.
Mbomb007
2

Python 2, 67 bytes

Com base nesta resposta , mas modificado para usar o Python 2, com um programa trivial 0para imprimir nada e sair.

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

Experimente online

mbomb007
fonte
1

RPL, 73 bytes

Com a página de código hp8.

Ligue o HP48 ou similar, ou atire o droid48 . Não se esqueça de -52 SFpara uma melhor visualização da pilha. Suponho que você já tenha empurrado a corda, por exemplo "ABC", na pilha. Em seguida, digite a seguinte função:

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

(Por conveniência, sugiro pressionar a tecla α duas vezes antes de digitar qualquer coisa, portanto, bloqueie o modo de entrada alfa. Mais tarde, basta usar a tecla DEL para cancelar os delimitadores de fechamento inseridos automaticamente. Basta usar a tecla ENTER para validar. Não esqueça o espaço após o facada.)

Essa função envia imediatamente para a pilha um programa auto-modificador, sob a forma de uma lista. (Mas a função acima não se modifica). Como o L no RPL significa originalmente LISP, pressionar a tecla EVAL realmente avaliará esse programa. Ele retorna o código de saída no nível dois da pilha e sai, modificado (sim, aqui é questionável), para um último EVAL. Portanto, pressione EVAL repetidamente até que o programa finalmente pare para cair no nível um da pilha. O código de saída final 0 aparece assim no nível um, com os códigos de saída anteriores acima. Se você esqueceu -52 SF, poderá navegar na pilha após cada EVAL pressionando a tecla ((saia deste modo de navegação com a tecla ON). A função acima aceita cadeias com caracteres 0x0 dentro, para criar essas cadeias 0 CHRe+são seus amigos. A auto-modificação consiste em remover o caractere usado da string incorporada (a SUB 2 SWAP PUTramificação). Portanto, o programa descartado é mais curto após cada EVAL. A 4 DROPNramificação garante que nenhuma instrução do OP seja respeitada, descartando, entre outros, o próprio programa. Claro que tudo isso pressupõe sua nota como um -55 SFadepto. Usuários de -55 SFserão banidos. Para sempre.

Presumo que exista uma solução RPL / 2 e que possa apresentar um código de saída unix real, mas o RPL / 2 tem uma introspecção limitada e não pode avaliar listas.

Nácar
fonte
Eu não acho que o uso de códigos auto-modificáveis ​​conta como um quine válido de acordo com nosso consenso, já que ele tem acesso ao seu próprio código-fonte. Vou perguntar ao OP em um comentário. Veja as postagens relacionadas: O que conta como uma solução adequada? ; O uso do SMBF conta como uma trapaça? <- este é o único que se aplica
mbomb007
1
Somente o programa gerado é auto-modificável, não a função que responde ao desafio. Mas eu concordo, isso é questionável! Foram adicionadas algumas edições para destacar isso.
Nacre
1

sed , 467 461 bytes

Os códigos de caracteres são difíceis:

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

Experimente online!

Caso contrário, a lógica é bastante direta: (1) escape de caracteres especiais (existem dois), (2) envolva em uma s/^/…/;q\1camada adicional , (3) repita.

Aqui está a saída para hello:

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

E um pequeno script que eu usei:

#!/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
fonte
Você não precisa se preocupar com novas linhas, pois a postagem diz que você receberá apenas caracteres entre 0x20 e 0x7E. Ótima solução! :)
Conor O'Brien
@ ConorO'Brien Oh, certo. Obrigado!
Eush77
1

PowerShell, 172 156 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"

A h3l}'{l0entrada resultará na próxima saída

Experimente online!

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, por sua vez, produzirá

Experimente online!

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

A última execução não produzirá nada e o código de saída será 0.

Experimente online!

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
fonte