Kod dizesi çıkışından çık


18

Belirli bir zaman, bu bir program veya fonksiyon yazmalısınız nonempty dize S arasında N yazdırılabilir ASCII karakterleri , çıkış kodu ile çıkılacak bir program çıkışı C , C de 0 konumunda ASCII kod noktası olan S . Yazdığınız bu program ek olarak bir P programı çıkarır , böylece çalıştırıldığında C ′ çıkış kodundan çıkar , burada C S S konumunda 1 konumundaki ASCII kod noktasıdır . Program P irade çıkışı başka bir program P ' . Bu işlem S'de karakter kalmayıncaya kadar tekrarlanır. Bu yapıldıktan sonra, hiçbir şey çıkarmamalısınız, bunu isteğe bağlı bir satırsonu izlemelidir; ve çıkış kodu 0 ile çıkmalıdır.

Arasındaki 0x20ve 0x7ekapsayıcı karakterler .

Bazı kurallar:

  • Kendini değiştiren programlara izin verilmez: kaynağı STDOUT'a vermelisiniz (veya başlangıçta değeri döndürmelisiniz)
  • Kendi kaynak kodunuzu okuyamazsınız.

Bayt cinsinden bu tür en kısa program kazanacaktır.

Bazı ilkel testler için bu yakut senaryo kullanılabilir. (İlk argüman, komut dosyasını çalıştırma şekliniz, ikincisi program ve üçüncüsü de giriş dizesidir.)

Varsayımsal Örnek

Diyelim ki program FOO. "ABC" dizesi verildiğinde çıktı alır BARA. Bu program kod 65ve çıkışlarla çıkar BARB. Bu da kod 66ve çıkışlarla çıkar BARC. Bu program kod 67ve çıkışlarla çıkar BAR!. Bu hiçbir şey çıktı ve kod ile çıkar 0.


Bunu yapmak Forth'ta çıkış kodu olarak sayılır mı? Diğer işletim sistemi hatalarını görmek için parametreyi değiştirin. 0Başarı. tio.run/nexus/…
mbomb007

@ mbomb007 Forth hakkında fazla bir şey bilmiyorum. Forth'da geleneksel olarak bir "hata kodu" nasıl kullanılır?
Conor O'Brien

Amacınızın işletim sistemi düzeyinde hata kodlarına sahip olup olmamasına bağlıdır. Sadece sayı önemliyse, 33 throwrastgele bir sayı atmak gibi bir şey yapabilirsiniz . İşletim sistemi düzeyi için negatifleri kullanırsınız ve uzaklık -512'dir. Çok da idk, ama buraya bakıyorum: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Yanıtlar:


6

Piton 2, 126 101 94 bayt

Bunu yaparken Python kodunun gerçek NUL bayt içermeyebileceğini buldum.

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

Çevrimiçi deneyin (Hata Ayıklama bilgilerindeki çıkış kodunu gösterir)


Aşağıdaki boş olmayan programların her birinde bir satır sonu beslemesi olduğunu unutmayın.

Giriş Helloiçin yukarıdaki çıkışlar:

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

hangi baskılar

...

hangi baskılar

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

hangi baskılar

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

hiçbir şey basmayan (boş program)

hiçbir şey basmaz ve 0 koduyla çıkar.


4

Python 3, 77 bayt

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

Bu kod STDIN'den girdi alır ve ilk programı STDOUT'a verir.

Girdi ise ABCDE, sonuçlar

 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 

burada her satır çıkış kodunu ve daha önce yürütülen programın çıktısını içerir (ilk satır ilk programdır).


Cevabınız benimki gibi ... tam tersi yönde yaptığınız için ... Kendimi bunun için saklıyorum.
Sızdıran Rahibe


@LeakyNun evet, ama cevabınızı başlangıç ​​noktası olarak kullanmadım, eğer demek istediğiniz
buysa

Sadece bunu düşünmeliydim diyorum.
Leaky Nun

@vaultah Sizinkini 67 bayta kadar golf yapacak mısınız yoksa ayrı bir cevap olarak mı göndermeliyim?
mbomb007

3

Piton 3 , 115 108 , 100 bayt

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

Çevrimiçi deneyin!


Giriş Helloiçin program yazdırır:

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

Yukarıdaki program yazdırır:

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

ve kod ile çıkar 72.

Çevrimiçi deneyin!


Yukarıdaki program yazdırılıyor

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

ve kod ile çıkar 101.

Çevrimiçi deneyin!


Yukarıdaki program yazdırır:

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

ve kod ile çıkar 108.

Çevrimiçi deneyin!


Yukarıdaki program yazdırır:

print("");exit(111)

ve kod ile çıkar 108.

Çevrimiçi deneyin!


Yukarıdaki program hiçbir şey yazdırmaz ve kodla çıkar 111.

Çevrimiçi deneyin!


Boş program hiçbir şey yazdırmaz ve kodla çıkar 0.

Çevrimiçi deneyin!


2
Boş program için bir TIO bağlantısı mı var? Bu sana adanmışlık!
Neil

2

C, 156 bayt

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

Çevrimiçi deneyin! (Çıkış kodunu görmek için hata ayıklama sekmesini açın.)

Girdiyi komut satırı argümanı olarak alır.

"ABC" girişi için, bu programın çıktısını alır

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

65 döndüren ve çıktılar

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

66 döndürür ve çıktılar

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

67 döndüren ve çıktılar

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

hiçbir şey çıktılamaz ve 0 döndürür.


@ mbomb007 Teşekkürler, şimdi düzeltildi (ve süreçte kısaldı).
Steadybox

2
Bu olduğunda onu sevmeliyim.
mbomb007

2

Python 2, 67 bayt

Bu cevaba dayanarak, 0hiçbir şey yazdırmamak ve çıkmak için önemsiz bir programla Python 2'yi kullanacak şekilde değiştirildi .

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

Çevrimiçi deneyin


1

RPL, 73 bayt

Hp8 kod sayfası ile.

HP48'inizi veya benzerlerini veya yangın droid48'inizi açın . -52 SFYığının daha iyi görüntülenmesi için unutmayın . Dize zaten, örneğin "ABC", yığın itti varsayalım . Ardından aşağıdaki işlevi girin:

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

(Kolaylık sağlamak için, herhangi bir şey yazmadan önce α tuşuna iki kez basmanızı öneririm, bu yüzden alfa giriş modunu kilitler. İkincisi, otomatik olarak eklenen kapatma sınırlayıcılarını iptal etmek için DEL tuşunu kullanın. Doğrulamak için ENTER tuşunu kullanmanız yeterlidir. bıçak operatörü.)

Bu işlev hemen yığının üzerine liste biçiminde kendi kendini değiştiren bir program gönderir. (Ancak yukarıdaki işlev kendini değiştirmez). RPL'deki L başlangıçta LISP'yi temsil ettiği için, EVAL tuşuna basmak gerçekten bu programı değerlendirecektir. Çıkış kodunu ikinci yığın seviyesinde döndürür ve ikinci bir EVAL için kendisini değiştirir (evet, burada sorgulanabilir). Bu yüzden, program sonunda kendini birinci seviye seviyesine bırakmak için duruncaya kadar EVAL tuşuna basın. Böylece nihai çıkış kodu 0, birinci çıkış kodu üzerinde, geçmiş çıkış kodları yukarıda görünür. Eğer unuttuysanız -52 SF, EV tuşuna basarak her EVAL'den sonra yığın içinde gezinebilirsiniz (bu gezinme modunu ON tuşu ile bırakın). Yukarıdaki işlev, bu tür dizeler oluşturmak için içinde 0x0 karakterli dizeleri kabul eder 0 CHRve+senin arkadaşların. Kendini değiştirme, kullanılan karakteri gömülü dizeden ( SUB 2 SWAP PUTdaldan) kaldırmayı içerir . Dolayısıyla, bırakılan program her EVAL'den sonra daha kısadır. 4 DROPNDal sağlayan çıkış şey diğerleri arasında programın kendisini bırakarak, OP talimat saygı duyulur. Tabii ki tüm bunlar notunuzun bir -55 SFusta olduğunu varsayar . Kullanıcıları -55 SFyasaklanacak. Sonsuza dek.

Bir RPL / 2 çözümünün var olduğunu ve gerçek bir unix çıkış kodunu içerebileceğini varsayıyorum, ancak afaik RPL / 2 sınırlı içgözleme sahip ve listeleri değerlendiremiyor.


Kendi kaynak koduna erişimi olduğundan, kendi kendini değiştiren kod sayımını oybirliğimize göre geçerli bir soru olarak düşünmüyorum. OP'ye bir yorumda soracağım. İlgili meta yayınlara bakın: Ne uygun bir soru olarak sayılır? ; SMBF kullanmak hile yapmak olarak sayılıyor mu? <- Bu geçerli
mbomb007

1
Sadece oluşturulan program kendi kendini değiştirir, zorluğa cevap veren fonksiyon değil. Ama katılıyorum, bu tartışmalı! Bunu vurgulamak için bazı düzenlemeler eklendi.
Sedef

1

sed , 467461 bayt

Karakter kodları zor:

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

Çevrimiçi deneyin!

Aksi takdirde, mantık oldukça basittir: (1) özel karakterlerden kaçın (iki tane vardır), (2) ek bir s/^/…/;q\1katmana sarın , (3) tekrarlayın.

İşte çıktı hello:

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

Ve kullandığım küçük bir senaryo:

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

Yeni satırlar için endişelenmenize gerek yok, çünkü yayında yalnızca 0x20 ile 0x7E arasında karakterler verilecek. Güzel çözüm! :)
Conor O'Brien

@ ConorO'Brien Oh, doğru. Teşekkürler!
eush77

1

PowerShell, 172156 bayt.

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"

h3l}'{l0Giriş sonraki çıkışı neden olacaktır

Çevrimiçi deneyin!

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

Hangi sırayla çıktı

Çevrimiçi deneyin!

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

Son çalıştırma hiçbir şey vermez ve çıkış kodu 0 olur.

Çevrimiçi deneyin!

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.