Uscita stringa di codice di uscita


18

È necessario scrivere un programma o funzione che, quando somministrato un non vuota stringa S di N caratteri ASCII stampabili , emette un programma che uscirà con codice di uscita C , dove C è il valore di codice ASCII in posizione 0 in S . Questo programma si scrive sarà inoltre l'output di un programma di P , in modo tale che, quando viene eseguito, esce con il codice di uscita C ' , dove C' è il valore di codice ASCII in posizione 1 in S . Programma P emetterà un altro programma P ′ . Questo processo si ripete fino a quando non ci sono più caratteri in S. Fatto ciò, non devi produrre nulla, seguito da una nuova riga opzionale; e dovrebbe uscire con il codice di uscita 0.

I caratteri tra 0x20e 0x7ecompreso.

Alcune altre regole:

  • Non sono consentiti programmi di modifica automatica: è necessario generare l'origine su STDOUT (o, inizialmente restituire un valore)
  • Non puoi leggere il tuo codice sorgente.

Vincerà il programma più breve in byte.

Per alcuni test rudimentali, è possibile utilizzare questo script ruby . (Il primo argomento è il modo in cui invochi lo script, il secondo è il programma e il terzo è la stringa di input.)

Esempio ipotetico

Di 'che il programma è FOO. Quando viene data la stringa "ABC", viene emessa BARA. Questo programma esce con codice 65e output BARB. Questo a sua volta esce con codice 66e uscite BARC. Questo programma esce con codice 67e output BAR!. Questo non genera nulla ed esce con il codice 0.


Fare questo conterebbe come codici di uscita in Forth? Modificare il parametro per visualizzare altri errori del sistema operativo. 0è successo. tio.run/nexus/…
mbomb007

@ mbomb007 Non so molto di Forth. È così che si userebbe convenzionalmente un "codice di errore" in Forth?
Conor O'Brien,

Dipende se il tuo obiettivo è avere codici di errore a livello di sistema operativo. Se conta solo il numero, puoi semplicemente fare qualcosa come 33 throwlanciare un numero arbitrario. Si utilizzano negativi per il livello del sistema operativo e l'offset è -512. Idk molto, ma sto guardando qui: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Risposte:


6

Python 2, 126 101 94 byte

Nel processo di realizzazione, ho scoperto che il codice Python potrebbe non contenere byte NUL letterali.

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

Provalo online (mostra il codice di uscita nelle informazioni di debug)


Si noti che ciascuno dei programmi non vuoti di seguito ha un avanzamento riga finale.

Per l'ingresso Hello, le uscite sopra:

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

quale stampa

...

quale stampa

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

quale stampa

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

che non stampa nulla (il programma vuoto)

che non stampa nulla ed esce con il codice 0.


4

Python 3, 77 byte

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

Questo codice prende l'input da STDIN e invia il primo programma a STDOUT.

Se l'input è ABCDE, i risultati sono

 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 

dove ogni riga contiene il codice di uscita e l'output del programma precedentemente eseguito (la prima riga è il primo programma).


La tua risposta è come la mia ... solo che l'hai fatto nella direzione opposta ... mi sto affrontando per quello.
Leaky Nun,


@LeakyNun sì, ma non ho usato la tua risposta come punto di partenza, se è questo che vuoi dire
vaultah

Sto solo dicendo che avrei dovuto pensarci.
Leaky Nun,

@vaultah Stai andando a golf tuo a 67 byte, o dovrei pubblicarlo come risposta separata?
mbomb007,

3

Python 3 , 115 108 100 100 byte

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

Provalo online!


Per l'input Hello, il programma stampa:

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

Il programma sopra stampa:

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

ed esce con il codice 72.

Provalo online!


Il programma sopra stampa

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

ed esce con il codice 101.

Provalo online!


Il programma sopra stampa:

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

ed esce con il codice 108.

Provalo online!


Il programma sopra stampa:

print("");exit(111)

ed esce con il codice 108.

Provalo online!


Il programma sopra non stampa nulla ed esce con il codice 111.

Provalo online!


Il programma vuoto non stampa nulla ed esce con il codice 0.

Provalo online!


2
Un collegamento TIO per il programma vuoto? Questa è dedizione per te!
Neil,

2

C, 156 byte

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);}

Provalo online!(Apri la scheda debug per vedere il codice di uscita.)

Accetta input come argomento della riga di comando.

Per l'ingresso "ABC", questo emette il programma

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];}

che restituisce 65 e genera

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];}

che restituisce 66 e genera

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];}

che restituisce 67 e genera

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];}

che non genera nulla e restituisce 0.


@ mbomb007 Grazie, ora è stato risolto (e si è ridotto nel processo).
Steadybox

2
Devo amarlo quando succede.
mbomb007,

2

Python 2, 67 byte

Basato su questa risposta , ma modificato per usare Python 2, con un banale programma 0per non stampare nulla ed uscire.

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

Provalo online


1

RPL, 73 byte

Con codepage hp8.

Accendi il tuo HP48 o simile o spegni Droid48 . Non dimenticare di -52 SFper una migliore visualizzazione dello stack. Presumo che tu abbia già inserito la stringa, ad esempio "ABC", nello stack. Quindi digitare la seguente funzione:

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

(Per comodità, suggerisco di premere due volte il tasto α prima di digitare qualsiasi cosa, quindi bloccare la modalità di input alpha. Ultimamente basta usare il tasto DEL per cancellare i delimitatori di chiusura inseriti automaticamente. Basta usare il tasto ENTER per confermare. Non dimenticare lo spazio dopo il operatore di pugnalata.)

Questa funzione invia immediatamente in pila un programma di modifica automatica, sotto forma di un elenco. (Ma la funzione sopra non si modifica da sola). Dato che L in RPL originariamente sta per LISP, premendo il tasto EVAL si valuterà davvero questo programma. Restituisce il codice di uscita al secondo livello dello stack e si lascia, modificato (sì, qui è discutibile), per un ultimo EVAL. Quindi premere ripetutamente EVAL fino a quando il programma non si interrompe infine per cadere a livello di stack uno. Il codice di uscita finale 0 appare quindi al primo livello, con i codici di uscita precedenti sopra. Se ti sei dimenticato di-52 SF , puoi navigare nello stack dopo ogni EVAL premendo il tasto ▴ (esci da questa modalità di navigazione con il tasto ON). La funzione sopra accetta stringhe con caratteri 0x0 all'interno, per creare tali stringhe 0 CHRe+sono i tuoi amici. L'auto-modifica consiste nel rimuovere il carattere usato dalla stringa incorporata (il SUB 2 SWAP PUTramo). Quindi il programma abbandonato è più breve dopo ogni EVAL. La 4 DROPNdiramazione assicura che l' nulla saranno esclusi. Per sempre.le istruzioni dell'OP vengono rispettate, eliminando tra l'altro il programma stesso. Naturalmente tutto ciò presuppone che la tua nota sia un -55 SFadepto. Utenti di-55 SF

Presumo che esista una soluzione RPL / 2, che potrebbe presentare un vero codice di uscita unix, ma afaik RPL / 2 ha un'introspezione limitata e non può valutare gli elenchi.


Non credo che usare il codice di auto-modifica sia un quine valido secondo il nostro consenso, dato che ha accesso al proprio codice sorgente. Chiederò all'OP in un commento. Vedi i meta post correlati: cosa conta come un vero quine? ; L'uso di SMBF conta come un chine chine? <- questo è quello che si applica
mbomb007,

1
Solo il programma generato si modifica da solo, non la funzione che risponde alla sfida. Ma sono d'accordo, questo è discutibile! Aggiunte alcune modifiche per evidenziarlo.
Madreperla,

1

sed , 467 461 byte

I codici carattere sono difficili:

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

Provalo online!

Altrimenti, la logica è piuttosto semplice: (1) sfuggire ai caratteri speciali (ce ne sono due), (2) avvolgere in un ulteriore s/^/…/;q\1 livello , (3) ripeti.

Ecco l'output per hello:

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

E una piccola sceneggiatura che ho usato:

#!/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

Non devi preoccuparti di newline, poiché il post dice che ti verranno dati solo caratteri tra 0x20 e 0x7E. Bella soluzione! :)
Conor O'Brien,

@ ConorO'Brien Oh, giusto. Grazie!
eush77,

1

PowerShell, 172 156 byte.

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"

L' h3l}'{l0ingresso produrrà l'uscita successiva

Provalo 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

Che a sua volta produrrà

Provalo 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

L'ultima esecuzione non genererà nulla e il codice di uscita sarà 0.

Provalo 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.