Keluar dari string output kode

18

Anda harus menulis sebuah program atau fungsi yang, ketika diberi tak kosong serangkaian S dari N karakter yang dapat dicetak ASCII , output program yang akan keluar dengan kode keluar C , di mana C adalah codepoint ASCII pada posisi 0 di S . Program ini Anda menulis akan tambahan keluaran program P , sehingga, ketika dijalankan, itu keluar dengan kode keluar C ' , di mana C' adalah codepoint ASCII pada posisi 1 di S . Program P akan menampilkan program P lainnya . Proses ini berulang hingga tidak ada karakter yang tersisa di S. Setelah ini dilakukan, Anda harus mengeluarkan apa-apa, diikuti oleh baris opsional baru; dan harus keluar dengan kode keluar 0.

Karakter antara 0x20dan 0x7einklusif.

Beberapa aturan lagi:

  • Program modifikasi diri tidak diperbolehkan: Anda harus menampilkan sumber ke STDOUT (atau, mengembalikan nilai awalnya)
  • Anda mungkin tidak membaca kode sumber Anda sendiri.

Program terpendek dalam byte akan menang.

Untuk beberapa pengujian yang belum sempurna, skrip ruby ​​ini dapat digunakan. (Argumen pertama adalah cara Anda menjalankan skrip, yang kedua adalah program, dan yang ketiga adalah string input.)

Contoh Hipotetis

Katakan programnya FOO. Ketika diberi string "ABC", itu menghasilkan BARA. Program ini keluar dengan kode 65dan keluaran BARB. Ini pada gilirannya keluar dengan kode 66dan ouputs BARC. Program ini keluar dengan kode 67dan keluaran BAR!. Ini tidak menghasilkan apa-apa, dan keluar dengan kode 0.

Conor O'Brien
sumber
Apakah melakukan ini dianggap sebagai kode keluar di Forth? Ubah parameter untuk melihat kesalahan OS lainnya. 0adalah Sukses. tio.run/nexus/…
mbomb007
@ mbomb007 Saya tidak tahu banyak tentang Forth. Begitukah cara konvensional menggunakan "kode kesalahan" di Forth?
Conor O'Brien
Itu tergantung apakah tujuan Anda adalah memiliki kode kesalahan tingkat OS. Jika hanya nomornya yang penting, Anda bisa melakukan sesuatu seperti 33 throwmelempar nomor sewenang-wenang. Anda menggunakan negatif untuk tingkat OS, dan offset -512. Idk banyak juga, tapi aku mencari di sini: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Jawaban:

6

Python 2, 126 101 94 byte

Dalam proses pembuatan ini, saya menemukan bahwa kode Python mungkin tidak mengandung byte NUL literal.

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

Cobalah online (menunjukkan kode keluar di info Debug)


Perhatikan bahwa masing-masing program non-kosong di bawah ini memiliki linefeed tambahan.

Untuk input Hello, output di atas:

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

yang mencetak

...

yang mencetak

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

yang mencetak

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

yang tidak mencetak apa-apa (program kosong)

yang tidak mencetak apa pun dan keluar dengan kode 0.

mbomb007
sumber
4

Python 3, 77 byte

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

Kode ini mengambil input dari STDIN dan mengeluarkan program pertama ke STDOUT.

Jika inputnya adalah ABCDE, hasilnya adalah

 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 

di mana setiap baris berisi kode keluar dan output dari program yang dieksekusi sebelumnya (baris pertama adalah program pertama).

kubah
sumber
Jawaban Anda seperti milik saya ... hanya saja Anda melakukannya dengan arah yang berlawanan ... Saya mempersenjatai diri saya untuk itu.
Leaky Nun
67 byte
mbomb007
@ LeakyNun ya, tapi saya tidak menggunakan jawaban Anda sebagai titik awal, jika itu yang Anda maksud
vaultah
Saya hanya mengatakan saya harus memikirkan itu.
Leaky Nun
@ vaultah Anda akan membuat golf milik Anda hingga 67 byte, atau haruskah saya mempostingnya sebagai jawaban terpisah?
mbomb007
3

Python 3 , 115 108 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%"")

Cobalah online!


Untuk input Hello, program mencetak:

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

Program di atas mencetak:

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

dan keluar dengan kode 72.

Cobalah online!


Program di atas mencetak

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

dan keluar dengan kode 101.

Cobalah online!


Program di atas mencetak:

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

dan keluar dengan kode 108.

Cobalah online!


Program di atas mencetak:

print("");exit(111)

dan keluar dengan kode 108.

Cobalah online!


Program di atas tidak mencetak apa pun dan keluar dengan kode 111.

Cobalah online!


Program kosong tidak mencetak apa pun dan keluar dengan kode 0.

Cobalah online!

Biarawati Bocor
sumber
2
TIO tautan untuk program kosong? Itu dedikasi untukmu!
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);}

Cobalah online! (Buka tab debug untuk melihat kode keluar.)

Mengambil input sebagai argumen baris perintah.

Untuk input "ABC", ini menampilkan program

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

yang mengembalikan 65 dan output

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

yang mengembalikan 66 dan output

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

yang mengembalikan 67 dan output

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

yang tidak menghasilkan apa-apa dan mengembalikan 0.

Steadybox
sumber
@ mbomb007 Terima kasih, sudah diperbaiki sekarang (dan prosesnya semakin pendek).
Steadybox
2
Harus suka kalau itu terjadi.
mbomb007
2

Python 2, 67 byte

Berdasarkan jawaban ini , tetapi dimodifikasi untuk menggunakan Python 2, dengan program sepele 0untuk mencetak apa pun dan keluar.

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

Cobalah online

mbomb007
sumber
1

RPL, 73 byte

Dengan halaman kode hp8.

Nyalakan HP48 Anda atau yang serupa, atau jalankan droid48 . Jangan lupa -52 SFuntuk visualisasi tumpukan yang lebih baik. Saya berasumsi Anda telah mendorong string, misalnya "ABC", di tumpukan. Kemudian masukkan fungsi berikut:

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

(Untuk kenyamanan saya sarankan untuk menekan tombol α dua kali sebelum mengetik apa pun, maka dari itu mengunci mode input alfa. Belakangan cukup gunakan tombol DEL untuk membatalkan pembatas penutup yang dimasukkan secara otomatis. Cukup gunakan tombol ENTER untuk memvalidasi. Jangan lupa spasi setelah operator penusuk.)

Fungsi ini segera mendorong stack program modifikasi sendiri, di bawah bentuk daftar. (Tetapi fungsi di atas tidak memodifikasi sendiri). Karena L dalam RPL awalnya adalah singkatan dari LISP, menekan tombol EVAL memang akan mengevaluasi program ini. Ia mengembalikan kode keluar pada stack tingkat dua, dan daun itu sendiri, dimodifikasi (ya, di sini patut dipertanyakan), untuk Tarahan terakhir. Jadi, tekan EVAL berulang kali hingga program akhirnya berhenti untuk menjatuhkan dirinya di tumpukan level satu. Karenanya, kode keluar terakhir 0 muncul di tingkat satu, dengan kode keluar terakhir di atas. Jika Anda lupa -52 SF, Anda dapat menavigasi di tumpukan setelah setiap EVAL dengan menekan tombol ▴ (tinggalkan mode navigasi ini dengan tombol ON). Fungsi di atas menerima string dengan 0x0 karakter di dalamnya, untuk membuat string seperti itu0 CHR dan+adalah temanmu Modifikasi diri terdiri dari menghapus char yang digunakan dari string yang tertanam ( SUB 2 SWAP PUTcabang). Oleh karena itu program yang dibatalkan lebih pendek setelah setiap EVAL. The 4 DROPNcabang menjamin keluaran tidak ada instruksi dari OP dihormati, menjatuhkan antara lain program itu sendiri. Tentu saja semua ini menganggap catatan Anda -55 SFmahir. Pengguna -55 SFakan dilarang. Selama-lamanya.

Saya berasumsi ada solusi RPL / 2, dan dapat menampilkan kode keluar unix yang nyata, tetapi afaik RPL / 2 memiliki introspeksi terbatas, dan tidak dapat mengevaluasi daftar.

Nacre
sumber
Saya tidak berpikir menggunakan penghitungan kode modifikasi diri sebagai quine yang valid sesuai dengan konsensus kami, karena ia memiliki akses ke kode sumbernya sendiri. Saya akan meminta OP dalam komentar. Lihat posting meta terkait: Apa yang dianggap sebagai quine yang tepat? ; Apakah menggunakan SMBF dianggap sebagai quine curang? <- yang ini yang berlaku
mbomb007
1
Hanya program yang dihasilkan yang memodifikasi sendiri, bukan fungsi yang menjawab tantangan. Tapi saya setuju, ini dipertanyakan! Menambahkan beberapa pengeditan untuk menyorot ini.
Nacre
1

sed , 467 461 byte

Kode karakter sulit:

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

Cobalah online!

Jika tidak, logikanya agak langsung: (1) keluar dari karakter khusus (ada dua), (2) membungkus s/^/…/;q\1lapisan tambahan , (3) ulangi.

Inilah output untuk hello:

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

Dan sedikit naskah yang saya gunakan:

#!/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
sumber
Anda tidak perlu khawatir tentang baris baru, karena posting mengatakan Anda hanya akan diberikan karakter antara 0x20 dan 0x7E. Solusi bagus! :)
Conor O'Brien
@ Conor'Brien Oh, benar. Terima kasih!
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"

The h3l}'{l0masukan akan menghasilkan output berikutnya

Cobalah 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

Yang pada gilirannya sendiri akan menampilkan

Cobalah 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

Jalankan terakhir akan menghasilkan apa-apa dan kode keluar akan menjadi 0.

Cobalah 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
sumber