Yığın taşmasına neden olacak en kısa kod nedir? [kapalı]


160

Stack Overflow'un genel lansmanını anmak için, yığın taşmasına neden olacak en kısa kod nedir? Herhangi bir dil hoş geldiniz.

ETA: Sadece bu soruya açık olmak gerekirse, ara sıra bir Şema kullanıcısı olduğumu görmek: kuyruk çağrısı "özyineleme" gerçekten yinelemedir ve iyi bir derleyici tarafından nispeten önemsiz bir şekilde yinelemeli bir çözüme dönüştürülebilecek herhangi bir çözüm sayılmak. :-P

ETA2: Şimdi bir “en iyi cevap” seçtim; mantık için bu gönderiye bakınız . Katkı yapan herkese teşekkür ederiz! :-)

Yanıtlar:


212

Bütün bu cevaplar ve Befunge yok mu? Ben adil bir miktar bahis hepsini en kısa çözüm:

1

Şaka yapmıyorum. Kendiniz deneyin: http://www.quirkster.com/iano/js/befunge.html

EDIT: Sanırım bunu açıklamam gerekiyor. 1 işlenen, 1'i Befunge'nin dahili yığınına iter ve başka bir şeyin olmaması, onu dilin kuralları altında bir döngüye sokar.

Sonunda, tercüman temin, olur kullanma - ve ben demek sonunda Befunge yığınını temsil JavaScript dizi tarayıcı yeniden tahsis etmek için çok büyük hale bir noktaya --hit. Aşağıdaki dillerin çoğunda olduğu gibi, daha küçük ve sınırlı bir yığınla basit bir Befunge yorumlayıcıya sahip olsaydınız, bu program daha belirgin bir taşmaya daha hızlı neden olur.


8
Hmm… ama bu gerçekten bir yığın taşması mı yoksa sadece sonsuz bir döngü mü? Benim HB tercüman yoktu değil taşması, sadece tabiri caizse, tatile gitti.
Konrad Rudolph

3
Sonsuz bir döngü değildir, çünkü 1 talimatı 1'i yığına iter. Sonunda Befunge yorumcunuzda yığın alanı bitecek, ancak biraz zaman alacak. :)
Patrick

18
Siz .. tarayıcımı kilitlediniz ve .. CPU fanımı aşırı hıza gönderdiniz.
Sam152

2
İnanılmaz! Bilgisayarım veya tarayıcım (Opera)
çökmedi

28
İşte daha hızlı taşan bir Befunge programı: " 32 numarasının 79 kopyasını, 1 numarasının 2 kopyası yerine, her iki seferde bir sarar.
KirarinSnow

291

Bu satırı okuyun ve söylediklerini iki kez yapın .


174

Ayrıca C # .net de deneyebilirsiniz

throw new StackOverflowException();

29
İçimdeki bilgiç, herhangi bir yığının taşmasına neden olmadığını söylüyor, sadece bir istisna atıyor. Köpekbalıkları tarafından saldırıya uğramanın en hızlı yolunun denizde durmak ve "Köpekbalığı saldırısı!" Diye bağırmak olduğunu söylemek gibidir. Buna rağmen oy kullanacağım. :)
Bernard

Bir fark var mı? Yakalayıp devam edebilir misin? Yoksa tam olarak c # bir stackoverflow gibi mi? O birinden ayırt edilemez olduğu bu durumda, her nasılsa bir stackoverflow Ancak ... vardır - Yukarıdaki tüm nedenlerle upvote
Mo

18
Ormanda, etrafta yakalanacak kimse olmayan bir yığın taşarsa, bir istisna atar mı?

'En kısa' demem, çünkü böyle bir astarı derleyebileceğiniz gibi değil. O does sanırım gerçi çabuk bir yığın taşması atmak.
Dominic K

159

Nemerle :

Bu derleyici bir StackOverflowException ile çöküyor :

def o(){[o()]}

119

Geçerli en iyi (x86 derlemesinde):

push eax
jmp short $-1

bu da 3 baytlık nesne kodu ( 50 EB FD) ile sonuçlanır . 16 bit kod için bu da mümkündür:

call $

bu da 3 bayt ( E8 FD FF) ile sonuçlanır .


6
"Derleme" (veya birleştirme) sonrasında baytların sayılması kod golf değildir.
Louis Brandy

37
Soru, "[...] Yığın taşmasına neden olacak en kısa kod nedir?" Kaynak kodu, yorumlanmış kod, makine kodu, nesne kodu veya yönetilen kod belirtmez ...
Anders Sandvig

Kayıt için Shin'in golf sunucusu, tüm ELF başlıklarınızı da sayacak olsa da, değerlendirilmek üzere nesne kodunu göndermenize izin verir. Hmm ....
Chris Jester-Young

Bunun bazı örnekleri için bkz. Örneğin golf.shinh.org/p.rb?FizzBuzz#x86 . (Dürüst olmak gerekirse, insanların 99 baytlık ELF ikili dosyalarını nasıl yapabileceğini bilmiyorum.) :-P
Chris Jester-Young

7
@lbrandy: Nesne kodunu doğrudan yazabilecek kadar insan var. Bunu x86 için yapamam, ancak belirli bir mikroişlemci için yapabilirim. Böyle bir kodu sayarım.
Joey

113

PIC18

TK tarafından verilen PIC18 cevap aşağıdaki talimatlarda sonuçları (ikili):

overflow
   PUSH
   0000 0000 0000 0101
   CALL overflow
   1110 1100 0000 0000
   0000 0000 0000 0000

Ancak, yalnızca CALL bir yığın taşması gerçekleştirir:

CALL $
1110 1100 0000 0000
0000 0000 0000 0000

Daha küçük, daha hızlı PIC18

Ancak RCALL (göreceli çağrı) hala daha küçüktür (global bellek değil, bu nedenle fazladan 2 bayta gerek yoktur):

RCALL $
1101 1000 0000 0000

PIC18'in en küçüğü 16 bit (iki bayt) olan tek bir komuttur. Bu döngü başına 2 komut döngüsü sürecektir. Her talimat döngüsü için 4 saat döngüsünde 8 saat döngüsüne sahipsiniz. PIC18'in 31 seviyeli bir yığını vardır, bu nedenle 32. döngüden sonra 256 saat döngüsünde yığını taşacaktır. 64MHz'de, yığını 4 mikro saniye ve 2 bayt içinde taşarsınız .

PIC16F5x (daha küçük ve daha hızlı)

Ancak, PIC16F5x serisi 12 bit talimatları kullanır:

CALL $
1001 0000 0000

Yine, döngü başına iki komut döngüsü, komut başına 4 saat, yani döngü başına 8 saat döngüsü.

Bununla birlikte, PIC16F5x'in iki seviyeli bir yığını vardır, bu nedenle üçüncü döngüde 24 talimatta taşar. 20MHz'de, 1.2 mikro saniye ve 1.5 .

Intel 4004

Intel 4004 8 bitlik bir çağrı altyordamı talimatı vardır:

CALL $
0101 0000

Bir ascii 'P' ye karşılık gelen meraklı için. Toplam 32.4 mikro saniye ve bir bayt için 24 saat döngüsü alan 3 seviyeli bir yığın ile . (4004'ünüzü overclock etmedikçe - hadi, istediğini biliyorsun.)

Hangi befunge cevap kadar küçük, ama mevcut yorumlayıcılarda çalışan befunge kodundan çok daha hızlı.


77

C #:

public int Foo { get { return Foo; } }

57

Hoot taşması!

//              v___v
let rec f o = f(o);(o)
//             ['---']
//             -"---"-

55

Her görevin doğru araca ihtiyacı vardır. Yığın taşmaları üretmek için optimize edilmiş SO Taşma diliyle tanışın :

so

7
Minimum kodla taşma oluşturmak için özel bir dil yapıyorsanız, (1) boş girişin yığın taşma kodu (muhtemelen montaj kodu girişinden oluşturulan yerel kodu çalıştıran küçük bir ikili) üretmesini istersiniz veya ) tüm giriş programları adı geçen ikili programı üretir.
Jared Updike

Hmmm, Turing tamamlanmadı. Henüz bir dil diyebilir misin bilmiyorum ...
Adam Davis

42

TeX:

\def~{~.}~

Sonuçlar:

! TeX kapasitesi aşıldı, üzgünüz [giriş yığını boyutu = 5000].
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
...
<*> \ def ~ {~.} ~

Lateks:

\end\end

Sonuçlar:

! TeX kapasitesi aşıldı, üzgünüz [giriş yığını boyutu = 5000].
\ end # 1 -> \ csname bitiş # 1
                      \ endcsname \ @checkend {# 1} \ genişletici \ endgroup \ if @ e ...
<*> \ end \ end

Beri ~aktiftir, bu yerine kullanılabilir \a. Ve LaTeX kodunu tamamen kazara keşfettim. :)
Josh Lee

35

Z-80 birleştirici - 0x0000 bellek konumunda:

rst 00

bir bayt - 0xC7 - mevcut bilgisayarı yığına itme ve 0x0000 adresine atlamanın sonsuz döngüsü.


2
Boş bir eprom rst 7 (= çağrı 0x0038) talimatları olan tüm 0xffs olacağını hatırlıyorum. Bu, bir osiloskopla donanımınızın hatalarını ayıklamak için yararlı olacaktır. Yığın defalarca taşmış, 0x0038'den 0xff okumaları ile serpiştirilmiş olarak, adres veriyolu 64K alanı içinde dönecektir.
Bill Forster


29

Başka bir PHP Örneği:

<?
require(__FILE__);

4
Parantezi atlayarak bile kısa devre yapabilirsiniz (ancak ilkinin yerine boşluk dahil).
alex

26

BASIC'te aşağıdakilere ne dersiniz:

10 GOSUB 10

(Korkarım TEMEL bir tercümanım yok, bu yüzden bu bir tahmin).


3
BASIC yığınsız bir dil olduğu için gerçekten yığın taşması değil. VB (bir yığını olan) bile, bir atlama çerçevesi oluşturmadan, sadece zıpladığından dolayı taşmaz.
Daniel Spiewak

21
Bu bir GOSUB, değil GOTO. O yana RETURNkesinlikle bir yığın kullanıyor, çağırıldığı yere s?
Tom

3
Evet katılıyorum. 80'lerde BASIC'te birçok yığın taşması yaşadım .
nickd

6
Bunu yabasic'te sadece eğlenmek için çalıştırdım ve neredeyse bilgisayarımı yıktı. Tanrıya şükür malloc sonunda başarısız oldu, ama yarın olmayacak şekilde çağrı yapıyorum.
Adam Rosenfield

2
Üzgünüz Adam ... birisinin yanlışlıkla tekrarlayan bir program yazdığı bir üniversitede geçirdiği zamanı hatırlatıyor: tüm bir Silikon Grafik sunucusunu devirdi.
stusmith

26

Cody'nin cevap yığınlarını sevdim, işte C ++ 'daki benzer katkım:

template <int i>
class Overflow {
    typedef typename Overflow<i + 1>::type type;
};

typedef Overflow<0>::type Kaboom;

Hiçbir şekilde bir kod golf girişi, ama yine de, bir meta yığını taşması için her şey! :-P


21

İşte C katkısı, 18 karakter ağırlığında:

void o(){o();o();}

Bu kuyruk çağrı optimize etmek çok daha zor! :-P


4
Benim için derlemez: "main" için tanımlanmamış referans: P
Andrew Johnson

1
Anlamıyorum: neden o () 2x diyelim?
Dinah

3
@Dinah: Yarışmamın kısıtlamalarından biri, kuyruk çağrısı optimizasyonunun özyineleme olarak sayılmamasıydı; sadece yinelemeli bir döngü. Eğer o () 'yi sadece bir kez yazdıysanız, bu kuyruk çağrısı şu şekilde optimize edilebilir (yetkili bir derleyici tarafından): "o: jmp o". 2 o çağrısı ile, derleyici "o: call o; jmp o" gibi bir şey kullanmalıdır. Yığın taşmasını sağlayan özyinelemeli "çağrı" talimatıdır.
Chris Jester-Young

Haklısın - bu kısma dikkat etmedim. Açıklama için teşekkürler.
Dinah


17

JavaScript

Birkaç karakteri daha kesmek ve kendimizi daha fazla yazılım mağazasından kovmak için:

eval(i='eval(i)');

15

Groovy:

main()

$ groovy stack.groovy:

Caught: java.lang.StackOverflowError
    at stack.main(stack.groovy)
    at stack.run(stack.groovy:1)
 ...

Oy verildi çünkü oldukça ilginç. Yine de Groovy derleyicisinde oldukça sinir bozucu bir zayıflık ortaya çıkarır (bu tür kuyruk çağrıları derleme zamanında sıralanabilir).
Daniel Spiewak

Bunun kuyruk çağrısı olduğundan emin misin? programın sonundan düşmenin tercüman kabuğunu çağırmaması mı?
Aaron


14
Person JeffAtwood;
Person JoelSpolsky;
JeffAtwood.TalkTo(JoelSpolsky);

İşte kuyruk özyineleme yok umuyoruz!


1
Hehe, komik. Sohbetlerle ilgili olarak, "yankı odası etkisi" fikri de oldukça ilginçtir. Taşmayı indükleyen yığın değil, yine de.
Chris Jester-Young

8
Bu bir boş gösterici istisnası olmaz mı? Üzgünüm, bunun bir şaka olduğunu biliyorum.
jamesh

12

C - En kısa değil, özyinelemesiz. Ayrıca taşınabilir değil: Solaris'te çöküyor, ancak bazı alloca () uygulamaları burada bir hata döndürebilir (veya malloc () öğesini çağırabilir). Printf () çağrısı gerekli.

#include <stdio.h>
#include <alloca.h>
#include <sys/resource.h>
int main(int argc, char *argv[]) {
    struct rlimit rl = {0};
    getrlimit(RLIMIT_STACK, &rl);
    (void) alloca(rl.rlim_cur);
    printf("Goodbye, world\n");
    return 0;
}

Ayrıca yığını gerçekten küçük ayarlamak için sadece "ulimit -s16" yapabilirsiniz. Yaklaşık 16 yaşından küçük ve program bile çalışmaz (görünüşte yetersiz argümanlar!).
Andrew Johnson

11

12 karakterde perl:

$_=sub{&$_};&$_

10 karakterde bash (işlevdeki boşluk önemlidir):

i(){ i;};i


11

Python :

so=lambda:so();so()

Alternatif:

def so():so()
so()

Python optimize edilmiş kuyruk çağırırsa ...:

o=lambda:map(o,o());o()

Şanslısınız, Python kuyruk arama optimizasyonu yapmaz; aksi takdirde, şu ana kadar iki cevap gibi diskalifiye edilirdi. :-P
Chris Jester-Young

10

Bu yazının ardından “en iyi yanıtı” seçiyorum. Ama önce, bazı orijinal katkıları kabul etmek istiyorum:

  1. aku'nunkiler. Her biri, yığın taşmasına neden olan yeni ve özgün bir yolu araştırıyor. F (x) ⇒ f (f (x)) yapma fikri, bir sonraki girişimde keşfedeceğim bir fikir. :-)
  2. Cody Nemerle derleyicisini veren yığın taşması .
  3. Ve (biraz kindarca), GateKiller bir yığın taşması istisnası atma konusunda. :-P

Yukarıdakileri sevdiğim kadarıyla, zorluk kod golfü yapmak ve katılımcılara adil olmak için, Befunge girişi olan en kısa koda “en iyi yanıtı” vermek zorundayım; Kimsenin bunu yenemeyeceğine inanmıyorum (Konrad kesinlikle denemesine rağmen), bu yüzden Patrick'i tebrik ediyorum!

Çok sayıda yığın-taşma-özyineleme çözümünü görünce, hiç kimsenin (mevcut yazı itibariyle) Y birleştiricisini getirmediğine şaşırdım (bkz . Bir astar için Dick Gabriel'in Y Nedeni, makalesi ). Aku f (f (x)) yaklaşımının yanı sıra Y birleştiricisini kullanan özyinelemeli bir çözümüm var. :-)

((Y (lambda (f) (lambda (x) (f (f x))))) #f)

8

İşte Scheme'den ilginç bir tane daha:

((lambda (x) (xx)) (lambda (x) (xx)))

Çok hoş ve onun için de iyi bir simetri var. Ayrıca, (lambda (x) (xx)) formülasyonunu kullanmak için: ((Y (lambda (x) (xx))) #f) de çok eğlencelidir!
Chris Jester-Young

Oh, bu güzel. Şema'daki kadar güzel olmasa da Ruby'de de çalışır: lambda {| x | x.call x}. çağrı lambda {| x | x.call x}
Wayne Conrad

7

Java

Java çözümünün biraz daha kısa versiyonu.

class X{public static void main(String[]a){main(a);}}

5
Veya (aynı sayıda karakter): genel statik void main (Dize ... a) {main ();}
Michael Myers

Veya TDD'li çocuklar için (aynı sayıda karakter): ortak sınıf ${@org.junit.Test kamu void $ () {$ ();}}
mhaller

Yine de en kısa değil (cevabımı gör)
Draemon


5

3 bayt:

label:
  pusha
  jmp label

Güncelleme

Göre (?) (? Eski) Intel belgelerinde , bu da 3 bayt:

label:
  call label


32 bit modunda 3 bayt. Güzel cevap, cevabı cevabımdan çok daha hızlı dolduracağını düşünüyor!
Chris Jester-Young

Penguin.cz/~literakl/intel/j.html#JMP'ye göre jmp, 8, 16 veya 32 bit göreceli hedef adresiyle 3 bayttır. Pusha da 1 bayt, bu da toplam 4
Anders Sandvig

Kısa, yakın ve uzak olmak üzere üç tür jmp vardır. Kısa jmp (0xEB opcode kullanılarak) iki bayttır. Hedef, bir sonraki talimattan -128 ile 127 bayt arasında olmalıdır. :-)
Chris Jester-Young

Belki sen haklısın. Benim montajcı kazmak ve doğrulamak için çok tembelim;;)
Anders Sandvig
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.