Ausgabe der Codezeichenfolge beenden

18

Sie müssen ein Programm oder eine Funktion schreiben, die bei Angabe einer nicht leeren Zeichenfolge S mit N druckbaren ASCII-Zeichen ein Programm ausgibt, das mit dem Beendigungscode C beendet wird , wobei C der ASCII-Codepunkt an Position 0 in S ist . Dieses von Ihnen geschriebene Programm gibt zusätzlich ein Programm P aus , so dass es beim Ausführen mit dem Exit-Code C 'beendet wird , wobei C' der ASCII-Codepunkt an Position 1 in S ist . Das Programm P gibt ein anderes Programm P 'aus . Dieser Vorgang wiederholt sich, bis in S keine Zeichen mehr vorhanden sind. Danach müssen Sie nichts mehr ausgeben, gefolgt von einem optionalen Zeilenumbruch. und sollte mit Exit-Code 0 beenden.

Die Zeichen zwischen 0x20und 0x7eeinschließlich.

Noch ein paar Regeln:

  • Selbstmodifizierende Programme sind nicht zulässig: Sie müssen die Quelle an STDOUT ausgeben (oder zunächst einen Wert zurückgeben).
  • Möglicherweise lesen Sie Ihren eigenen Quellcode nicht.

Das kürzeste derartige Programm in Bytes gewinnt.

Für einige rudimentäre Tests kann dieses Ruby-Skript verwendet werden. (Das erste Argument ist die Art und Weise, wie Sie das Skript aufrufen, das zweite das Programm und das dritte die Eingabezeichenfolge.)

Hypothetisches Beispiel

Sprich das Programm ist FOO. Wenn die Zeichenfolge "ABC" angegeben wird, wird ausgegeben BARA. Dieses Programm wird mit Code 65und Ausgaben beendet BARB. Dies wird wiederum mit Code 66und Ausgaben beendet BARC. Dieses Programm wird mit Code 67und Ausgaben beendet BAR!. Dies gibt nichts aus und wird mit Code beendet 0.

Conor O'Brien
quelle
Würde dies in Forth als Exit-Code gelten? Ändern Sie den Parameter, um andere Betriebssystemfehler anzuzeigen. 0ist Erfolg. tio.run/nexus/…
mbomb007
@ mbomb007 Ich weiß nicht viel über Forth. Würde man auf diese Weise herkömmlicherweise einen "Fehlercode" in Forth verwenden?
Conor O'Brien
Es hängt davon ab, ob Sie Fehlercodes auf Betriebssystemebene haben möchten. Wenn nur die Zahl zählt, können Sie einfach 33 throweine beliebige Zahl werfen. Sie verwenden Negative für die Betriebssystemebene und der Offset beträgt -512. Idk auch viel, aber ich suche hier: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Antworten:

6

Python 2, 126 101 94 Bytes

Dabei stellte ich fest, dass Python-Code möglicherweise keine wörtlichen NUL-Bytes enthält.

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

Versuchen Sie es online (zeigt den Exit-Code in der Debug-Info)


Beachten Sie, dass jedes der folgenden nicht leeren Programme einen nachgestellten Zeilenumbruch hat.

Für die Eingabe gelten Hellodie obigen Ausgaben:

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

welche druckt

...

welche druckt

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

welche druckt

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

das druckt nichts (das leere Programm)

das druckt nichts und beendet mit Code 0.

mbomb007
quelle
4

Python 3, 77 Bytes

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

Dieser Code nimmt Eingaben von STDIN entgegen und gibt das erste Programm an STDOUT aus.

Wenn die Eingabe ist ABCDE, sind die Ergebnisse

 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 

Dabei enthält jede Zeile den Exit-Code und die Ausgabe des zuvor ausgeführten Programms (die erste Zeile ist das erste Programm).

Vaultah
quelle
Ihre Antwort ist wie meine ... nur, dass Sie es in die entgegengesetzte Richtung getan haben ...
Undichte Nonne
67 bytes
mbomb007
@LeakyNun ja, aber ich habe deine Antwort nicht als Ausgangspunkt genommen, wenn du das meinst
Vaultah
Ich sage nur, ich hätte darüber nachdenken sollen.
Undichte Nonne
@vaultah Wirst du deines auf 67 Bytes golfen, oder soll ich es als separate Antwort posten?
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%"")

Probieren Sie es online!


Für die Eingabe Hellodruckt das Programm:

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

Das obige Programm druckt:

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

und wird mit Code beendet 72.

Probieren Sie es online!


Das obige Programm wird gedruckt

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

und wird mit Code beendet 101.

Probieren Sie es online!


Das obige Programm druckt:

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

und wird mit Code beendet 108.

Probieren Sie es online!


Das obige Programm druckt:

print("");exit(111)

und wird mit Code beendet 108.

Probieren Sie es online!


Das obige Programm gibt nichts aus und wird mit Code beendet 111.

Probieren Sie es online!


Das leere Programm gibt nichts aus und wird mit Code beendet 0.

Probieren Sie es online!

Undichte Nonne
quelle
2
Ein TIO-Link für das leere Programm? Das ist Hingabe für Sie!
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);}

Probieren Sie es online! (Öffnen Sie die Debug-Registerkarte, um den Exit-Code zu sehen.)

Nimmt Eingaben als Befehlszeilenargument.

Bei Eingang "ABC" wird das Programm ausgegeben

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

Dies gibt 65 und Ausgänge zurück

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

was 66 und Ausgänge zurückgibt

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

was 67 und Ausgänge zurückgibt

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

was nichts ausgibt und 0 zurückgibt.

Steadybox
quelle
@ mbomb007 Danke, es ist jetzt behoben (und es wurde dabei kürzer).
Steadybox
2
Muss ich lieben, wenn das passiert.
mbomb007
2

Python 2, 67 Bytes

Basierend auf dieser Antwort , aber geändert, um Python 2 zu verwenden, mit einem einfachen Programm 0, um nichts zu drucken und zu beenden.

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

Probieren Sie es online aus

mbomb007
quelle
1

RPL, 73 Bytes

Mit HP8-Codepage.

Schalten Sie Ihr HP48 oder ähnliches ein oder feuern Sie droid48 ab . Vergessen Sie nicht, -52 SFfür eine bessere Visualisierung des Stapels. Ich gehe davon aus, dass Sie die Zeichenfolge bereits verschoben haben, z. B. "ABC"auf dem Stapel. Geben Sie dann die folgende Funktion ein:

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

(Der Einfachheit halber schlage ich vor, die α-Taste zweimal zu drücken, bevor Sie etwas eingeben, um den Alpha-Eingabemodus zu sperren. Verwenden Sie in letzter Zeit einfach die ENTF-Taste, um die automatisch eingefügten schließenden Begrenzer zu löschen. Verwenden Sie einfach die EINGABETASTE, um die Eingabe zu bestätigen. Vergessen Sie nicht das Leerzeichen nach dem Stichoperator.)

Diese Funktion drückt sofort ein selbstmodifizierendes Programm in Form einer Liste auf den Stapel. (Die obige Funktion ändert sich jedoch nicht von selbst). Da das L in RPL ursprünglich für LISP steht, wird dieses Programm durch Drücken der EVAL-Taste ausgewertet. Es gibt den Exit-Code auf Stack-Ebene zwei zurück und lässt sich für ein letztes EVAL modifiziert (ja, hier ist es fraglich). Drücken Sie also mehrmals EVAL, bis das Programm endgültig stoppt und sich auf Stapelebene eins befindet. Der endgültige Beendigungscode 0 wird daher auf der ersten Ebene mit den vorherigen Beendigungscodes angezeigt. Wenn du vergessen hast, deine Freunde zu sein. Die Selbstmodifikation besteht aus dem Entfernen des verwendeten Zeichens aus der eingebetteten Zeichenfolge (dem Zweig). Daher ist das verworfene Programm nach jedem EVAL kürzer. Die Verzweigung sorgt für die Ausgabe nichts-52 SF können Sie nach jedem EVAL durch Drücken der Taste ▴ im Stapel navigieren (verlassen Sie diesen Navigationsmodus mit der Taste ON). Die obige Funktion akzeptiert Strings mit 0x0 Zeichen, um solche Strings 0 CHRund zu erstellen+SUB 2 SWAP PUT4 DROPN Anweisung vom OP beachtet wird, und verwirft unter anderem das Programm selbst. Natürlich setzt all dies voraus, dass Ihre Notiz ein -55 SFExperte ist. Nutzer von -55 SFsollen gebannt werden. Für immer.

Ich gehe davon aus, dass eine RPL / 2-Lösung vorhanden ist und einen echten Unix-Exit-Code enthalten könnte, aber afaik RPL / 2 verfügt über eine eingeschränkte Introspektion und kann keine Listen auswerten.

Perlmutt
quelle
Ich denke nicht, dass die Verwendung von selbstmodifizierendem Code nach unserem Konsens als gültiger Quine gilt, da er Zugriff auf seinen eigenen Quellcode hat. Ich werde das OP in einem Kommentar fragen. Siehe verwandte Meta-Posts: Was zählt als eine richtige Quine? ; Zählt die Verwendung von SMBF als Betrug? <- Dies ist diejenige, die gilt
mbomb007
1
Nur das generierte Programm ändert sich selbst, nicht die Funktion, die die Herausforderung beantwortet. Aber ich stimme zu, das ist fraglich! Es wurden einige Änderungen hinzugefügt, um dies hervorzuheben.
Perlmutt
1

sed , 467 461 Bytes

Zeichencodes sind schwer:

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

Probieren Sie es online!

Ansonsten ist die Logik recht einfach: (1) Escape-Sonderzeichen (es gibt zwei), (2) Wrap-In-Zusatzzeichen s/^/…/;q\1 Ebene einschließen, (3) Wiederholen.

Hier ist die Ausgabe für hello:

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

Und ein kleines Skript, das ich benutzt habe:

#!/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
quelle
Sie brauchen sich keine Gedanken über Zeilenumbrüche zu machen, da der Beitrag besagt, dass Sie nur Zeichen zwischen 0x20 und 0x7E erhalten. Schöne lösung! :)
Conor O'Brien
@ ConorO'Brien Oh, richtig. Vielen Dank!
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"

Die h3l}'{l0Eingabe ergibt die nächste Ausgabe

Probieren Sie es 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

Was in der eigenen Runde ausgegeben wird

Probieren Sie es 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

Der letzte Lauf gibt nichts aus und der Beendigungscode ist 0.

Probieren Sie es 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
quelle