Lingkaran penghancuran otomatis terpendek


61

Tugas Anda adalah untuk menulis sebuah program penuh atau fungsi yang tidak mengambil input dan menjalankan jenis loop ( while, for, foreach, do, do-while, do-loop, goto, rekursi, dll) yang akan berakhir dalam menyebabkan kesalahan, yang berarti bahwa program harus berhenti sendiri berjalan dan keluar.

Aturan:

  1. Kesalahan harus merupakan kesalahan run-time, pengecualian tidak tertangani, atau apa pun yang membuat program berakhir dengan sendirinya.
  2. Kesalahan harus menghasilkan berhenti dan keluar dari program tanpa memanggil secara eksplisit exit;(atau setara) di beberapa titik.
  3. Pesan seperti Warning:,, Notice:dll, yang tidak menyebabkan program berakhir dengan sendirinya tidak valid. Misalnya dalam pembagian PHP dengan nol menghasilkan Warningpesan tetapi program tidak akan berhenti dan akan tetap berjalan, ini bukan jawaban yang valid.
  4. Loop harus menjalankan setidaknya satu siklus penuh. Dengan kata lain kesalahan bisa terjadi mulai dari siklus kedua dan selanjutnya. Ini untuk menghindari kesalahan menggunakan sintaksis kode yang salah: kode harus benar secara sintaksis.
  5. Perulangan dapat menjadi tak terbatas (contoh for(;;);) jika menghormati aturan yang disebutkan di atas, tetapi harus tidak lebih dari 2 menit untuk mengakhiri sendiri dalam kesalahan run-time.
  6. Rekursi tanpa Optimasi Panggilan Ekor tidak valid ( 1 , 2 ).
  7. Ini adalah sehingga kode terpendek menang.
  8. Celah standar dilarang.

Contoh C # ( tes online ):

using System;
public class Program {
    public static void Main() {
        int i;
        int[] n;
        n = new int[5];
        for(i=0; i<7; i++) {
            n[i] = i;
            Console.WriteLine(n[i]);
        }
    }
}


Output: 

0
1
2
3
4
Run-time exception (line 9): Index was outside the bounds of the array.

Stack Trace:

[System.IndexOutOfRangeException: Index was outside the bounds of the array.]
  at Program.Main(): line 9

Papan peringkat:

var QUESTION_ID=104323,OVERRIDE_USER=59718;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important;font-family:Arial,Helvetica; font-size:12px}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Terima kasih kepada Martin Ender untuk Cuplikan Leaderboard


Supaya jelas, rekursi tanpa TCO dapat digunakan selama kesalahan tidak ada hubungannya dengan terlalu banyak rekursi, benar? (Misalnya, fungsi rekursif yang kesalahan pada rekursi kedua)
ETHproduksi

@ETHproductions Disarankan oleh Dennis dalam obrolan: "Mungkin sulit untuk memutuskan apakah siklus penuh telah selesai dalam kasus ini [rekursi]. Rekursi ekor agak sesuai dengan tagihan, tetapi hanya TCO yang benar-benar menyelesaikan siklus jika eksekusi dibatalkan. karena kesalahan. [...] Saya akan mengatakan rekursi tanpa TCO tidak valid. "
Mario

Dalam for(a;b;c)d;, setelah pernyataan mana yang mengakhiri siklus pertama? Apakah sah untuk melanggar pernyataan pertama c?
Hedi

1
@Hedi Inilah pendapat saya yang sederhana (bukan OP): Semua entri harus menyelesaikan satu siklus penuh, yang berarti mereka harus memasuki siklus kedua ; ini berarti bahwa setidaknya satu pernyataan dijalankan untuk kedua kalinya. Karena urutan eksekusi dalam contoh Anda adalah a, b, d, c, b, d, c, ..., badalah awal dari siklus, dan harus dijalankan setidaknya untuk kedua kalinya.
ETHproduksi

2
Saya tidak ingin memulai masalah tetapi karena program (fungsi dalam hal ini) tidak seharusnya mengambil input apa pun, semua solusi rekursif yang memiliki parameter tidak valid karena parameter adalah input.
BrainStone

Jawaban:


33

MATL , 5 1 byte

Ide diambil dari jawaban CJam @ MartinEnder

`

Cobalah online!

`    % Do...while loop
     % Implicit end. The loop continues if the top of the stack is true.
     % After the first iteration, since the stack is empty, the program 
     % implicitly tries to take some non-existing input, and finishes
     % with an error

Versi lama

2:t"x

Cobalah online!

2:   % Push [1 2]
t    % Duplicate
"    % For each (i.e. do the following twice)
  x  %   Delete top of the stack. Works the first time. The second it tries to
     %   implicitly take some non-existing input, and finishes with an error

3
Bekerja offline juga. Tanpa input berarti Anda dapat menerima input kosong.
Dennis

@ Dennis Hm program offline akan terus menunggu input pengguna. Input bersifat interaktif, yaitu yang diminta sesuai kebutuhan dalam versi offline. Jadi program akan menunggu tanpa batas. Tidak yakin itu diperhitungkan?
Luis Mendo

Tidak begitu yakin bagaimana MATL bekerja secara internal, tetapi jika Anda menjalankannya di lingkungan yang tidak mampu meminta input (seperti backend TIO), ia tidak akan bisa mendapatkan input apa pun. Juga, menekan Ctrl-D atau padanan yang bergantung pada OS harus diizinkan mengirim input kosong.
Dennis

35

Python, 16 byte

Pendekatan 0 divisi yang tidak menarik:

for x in 1,0:x/x

Iterasi pertama menghitung 1 / 1, yang berfungsi dengan baik. Iterasi kedua mencoba untuk menghitung 0 / 0, menghasilkan ZeroDivisionErrordilemparkan.

17 byte (favorit pribadi)

i=1
while i:del i

Awalnya, i=1yang benar, jadi loop dimasukkan.

Pertama kali loop dijalankan, variabel idihapus.

Ini berarti bahwa, yang kedua kalinya, ibukan lagi sebuah variabel dan karenanya evaluasinya gagalNameError: name 'i' is not defined.


Solusi 15 byte lainnya adalah def _():_()(baris baru) _(), karena Python tidak mengoptimalkan rekursi ekor. Namun, ini melanggar aturan # 6.


Solusi 17 byte juga berfungsi jika Anda mengganti while idengan while 1karena mencoba untuk menghapus ilagi;
user6245072

2
@ user6245072 ya, kedua snippet dapat dimodifikasi secara sepele untuk banyak solusi yang berfungsi
FlipTack

Anda dapat menggunakan deltrik dengan built-in untuk mencukur beberapa: while 1:del id.
DSM


18

Jelly , 3 2 byte

Ṿß

Membunuh dirinya sendiri dengan kehabisan memori. Lokal melakukannya setelah ~ 100 detik.

Cobalah online! (sertifikat kematian di laci Debug )

Bagaimana itu bekerja

Ṿß  Main link. Argument: x. Implicit first argument: 0

Ṿ   Uneval; yield a string representation of x.
 ß  Recursively call the main link.
    Jelly uses TCO, so the first cycle finishes successfully before entering
    the next one.

Beberapa iterasi pertama menghasilkan:

'0'
'”0'
'””,”0'
'””,””,”,,””,”0'
'””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”0'
'””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”,,”,,””,”,,”,,””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”0'

Setelah itu, menjadi sangat buruk, sangat cepat.


Berapa batas memori jelly?
tuskiomi

Jelly tidak memiliki batas memori eksplisit, jadi apa pun yang Python dapat alamat. Penggunaan memori berlipat ganda dengan setiap iterasi, jadi ini harus menghabiskan semua memori yang tersedia agak cepat.
Dennis

28
Jadi setiap 2 tahun, kita akan dapat melakukan iterasi lain
tuskiomi

Jadi akankah gagal kondisi # 5 pada mesin lambat dengan banyak RAM?
Fisikawan Gila

@MadPhysicist Itu benar. Ini adalah masalah yang melekat dengan batas waktu. Kepatuhan sangat tergantung pada mesin mana program dijalankan.
Dennis

13

V , 2 byte

òl

Cobalah online!

Ini adalah tantangan sempurna untuk V karena saya sudah melakukan itu sepanjang waktu! Faktanya, V bahkan tidak memiliki kondisional, ia hanya memiliki fungsi yang dapat memecah kesalahan. Dalam hal ini, òberarti "ulangi selamanya" dan lberarti "bergerak ke kanan".

Dalam buffer kosong (tanpa input) ini akan merusak pass pertama dan tidak menghasilkan output. Jika ada yang input, akan merusak setelah kami bergerak posting karakter terakhir dari input, dan output semua input (membuat ini juga program kucing)


3
Tunggu, lberarti "bergerak ke kanan"? Bukan "move left"?
Conor O'Brien

1
@ Conor'Brien ya. Sebenarnya ada beberapa alasan historis yang bagus untuk ini.
DJMcMayhem

3
Tantangannya membutuhkan jawaban untuk crash pada iterasi kedua atau lebih baru, bukan pada iterasi pertama.
Martin Ender

11

JavaScript (ES6), 13 byte

f=_=>f(_?a:1)

Ini adalah fungsi rekursif yang berjalan dengan baik sekali, lalu melempar ReferenceError: a is not defineddan berhenti.

Berikut adalah versi 15-byte non-ES6:

for(i=0;;)i=i.a

Ini berjalan baik sekali, lalu melempar TypeError: i is undefineddan berhenti.


10

Bash 4.2, 22 byte

exec $0 $@ $[2**$#%-1]

Tidak berfungsi di TIO karena memiliki Bash 4.3, dan bug yang saya andalkan akhirnya diperbaiki.

Verifikasi

$ xxd -c 22 -g 22 self-destruct
0000000: 6578656320243020244020245b322a2a2423252d315d  exec $0 $@ $[2**$#%-1]
$ ./self-destruct
Floating point exception

Ini macet setelah program mencoba untuk menghitung 2 63 mod -1 , yang macet di Bash 4.2 dan versi yang lebih lama karena bug yang dikenal.


10

PHP, 22 21 20 18 byte

Ini bergantung pada PHP yang memungkinkan seseorang untuk memberikan nama fungsi ke variabel dan mencoba menjalankannya.

Ini hanya menggabungkan nama pifungsi dua kali. Ini membunuh PHP dengan Fatal Error: Uncaught Error: Call to undefined function pipi() in [...][...].

while($x.=pi)$x();

Ini berfungsi mirip dengan jawaban lama saya.


Jawaban lama, 20 byte

PHP memungkinkan Anda untuk menambah karakter, menggunakan operator increment. Ini hanya berfungsi pada a-zjangkauan, tetapi cukup.

for($x=pi;;)$x=$x();

Saya percaya ini memenuhi semua poin yang diperlukan dan loop tidak berjalan sekali.

Anda dapat melihat apakah karena Anda akan mendapatkan kesalahan Fatal error: Function name must be a string.


Cara kerjanya, langkah demi langkah:

  • Tetapkan piuntuk $x.
    Karena pisedang digunakan sebagai konstanta, PHP akan memeriksa jika ada.
    Karena tidak, PHP menampilkan pesan peringatan Use of undefined constant pi - assumed 'pi'(Pada dasarnya: karena konstanta tidak ada, diasumsikan sebagai string)
  • Ulangi pertama kali
    • Jalankan fungsinya $x().
      Karena $xmemiliki nilai pi, itu akan menjalankan fungsinya pi().
  • Simpan nilai dalam $x.
    $xsekarang memiliki π, bukanpi
  • Ulangi untuk kedua kalinya
    • Jalankan fungsinya $x().
      Karena $xmemiliki π, ia akan menjalankan fungsinya 3.14159...().
    • π bukan string, membunuh program pada titik ini dengan a Fatal Error.

Terima kasih kepada @Titus untuk menemukan pi()fungsinya, menyelamatkan saya 1 byte!


Bagus, tapi saya pikir itu tidak valid. Itu tidak benar-benar menjalankan loop sekali. Anda kenaikan $xuntuk abtsebelum tubuh loop berjalan. Anda bisa memperbaikinya dengan menambah setelah loop.
aross

Saya memikirkan pendekatan yang berbeda
aross

@aross Duh, Anda benar, itu tidak valid. Selisihnya di tempat yang salah. Ini berfungsi sebagaimana mestinya sekarang. Anda dapat mencoba berlari for($x=abs;;++$x)echo$x,$x();untuk menguji. Seharusnya terlihat abs0abt Fatal error[...]. Atau serupa.
Ismael Miguel

1
Anda bisa menggunakan pibukan abs. Itu bahkan tidak menghasilkan peringatan sebelum melemparkan fatal.
Titus

@ Titus aku benar-benar lupa tentang fungsi itu! Saya tahu bahwa fungsi _ini didefinisikan dalam beberapa sistem, tetapi tidak dapat diandalkan. Tetapi terima kasih telah menemukan itu!
Ismael Miguel

10

GNU sed , 15 13 5 bytes

-2 Terima kasih seshoumara
-8 Terima kasih kepada zeppelin

H;G;D
  1. Tambahkan baris baru dan ruang terus ke ruang pola.
  2. Menambahkan baris baru dan ruang pola ke ruang penahanan.
  3. Menghapus hingga baris baru pertama dan memulai kembali.

Ini dengan cepat kehabisan memori:

$ time (echo|sed 'H;G;D')
sed: couldn't re-allocate memory

real    0m1.580s
user    0m0.545s
sys     0m1.012s

Hai, bagaimana s:a\?:&a:g? Ini 1 byte lebih sedikit dan menggandakan ukuran pola per iterasi juga.
seshoumara

@seshoumara Saya tidak berpikir itu akan cocok dengan apa pun ketika ruang pola kosong, jadi itu tidak akan pernah membuat penggantian pertama.
Riley

@seshoumara echo -n | sed 's:a\?:&a:g'dan tidak mendapat hasil. Itu akan sama dengan sed 's::a:'yang tidak cocok dengan apa pun.
Riley

Dengan echo -nbenar-benar tidak ada yang dilewatkan ke sed, tetapi sed tidak dapat memulai tanpa input oleh desain. Periksa tautan meta ini untuk melihat bahwa itu echo|sedadalah cara yang diterima untuk memulai dan tantangan yang menerapkan aturan tidak ada input.
seshoumara

@seshoumara Saya pikir itu masih akan memberinya string kosong. Itu sepertinya berhasil kalau begitu. Terima kasih!
Riley

9

R, 22 25 22 20 18 byte

Sunting: Terima kasih kepada @Mego karena telah menunjukkan bahwa R tidak mendukung pengoptimalan panggilan ekor.

Sunting4: Menemukan solusi yang lebih pendek yang sederhana namun cukup rumit.

repeat(ls(T<-T-1))

Jawabannya menggunakan variabel kebenaran boolean bawaan, Tyang dikurangi dengan tak terbatas dalam loop berulang. Fungsi ls()ini disebut setiap iterasi yang mencantumkan semua objek di lingkungan saat ini. Namun, argumen pertama namemenentukan dari lingkungan mana untuk membuat daftar objek. Dari dokumentasi-R kami menemukan bahwa:

Argumen nama dapat menentukan lingkungan dari mana nama objek diambil dalam salah satu dari beberapa bentuk: sebagai integer (posisi dalam searchdaftar); sebagai nama karakter string elemen dalam daftar pencarian; atau secara eksplisit environment(termasuk menggunakan sys.frameuntuk mengakses panggilan fungsi yang sedang aktif).

Ini terutama berarti bahwa dalam iterasi pertama kita menjalankan ls(-1)yang akan kembali character(0)(standar ketika mencoba mengakses elemen yang tidak ada everything-except-the-firstdari objek tipe karakter apa pun). Selama iterasi kedua, Tdikurangi oleh dua dan selanjutnya kami memanggil ls(-3)yang pada gilirannya mengembalikan kesalahan:

Error in as.environment(pos) : invalid 'pos' argument

Ini karena kami mencoba membuat daftar everything-except-the-thirdelemen tetapi lingkungan lokal hanya berisi variabel Tpada titik ini (dengan demikian, ls()akan mengembalikan daftar panjang 1pada iterasi ini) dan kesalahan dikembalikan.


1
Itu tidak terdengar seperti rekursi dilakukan dengan optimasi panggilan ekor, jika ada batas rekursi.
Mego

@Mego Setelah beberapa penggalian di sekitar saya menemukan bahwa R memang tidak mendukung optimasi panggilan ekor jadi jawaban ini tidak valid (tidak pernah mendengar konsep sebelumnya). Akan berubah menjadi jawaban yang valid sebentar lagi.
Billywob

9

Befunge-93, 3 byte (mungkin 1 atau 0)

!%!

Cobalah online!

Pada iterasi pertama loop, stack kosong, yang setara dengan semua nol. Operasi !(bukan) dengan demikian mengubah tumpukan bagian atas menjadi 1, dan operasi %(modulo) menghitung 0 mod 1, meninggalkan 0. !Operasi berikutnya mengubah 0 ke 1 sebelum penghitung program membungkus dan memulai loop lagi.

Pada iterasi kedua, !operasi pertama mengubah 1 yang sekarang di atas tumpukan menjadi 0. %Operasi kemudian menghitung 0 mod 0, yang menghasilkan pembagian dengan kesalahan nol pada penerjemah referensi, dan dengan demikian menghentikan program.

Ada juga jawaban 1 byte yang lebih membosankan, meskipun saya tidak yakin apakah ini dianggap valid.

"

Cobalah online!

"Perintah ini memulai string, sehingga setiap ruang pada sisa baris didorong ke tumpukan sampai penghitung program membungkus dan menemukan "lagi menutup string. Maka perlu membungkus kedua kalinya untuk mengulangi proses memulai string lain dan mendorong 79 spasi lain ke stack. Akhirnya ini akan kehabisan memori (perilaku penerjemah referensi) atau menghasilkan stack overflow.

Sekarang jika Anda ingin benar-benar menjalankan aturan, ada juga solusi nol byte secara teknis.


Jika Anda mengambil putusan ini untuk mengartikan bahwa penerjemah mana pun mendefinisikan bahasa (seperti yang dilakukan banyak orang di sini), maka kita dapat mengasumsikan saat itu bahwa bahasa Befunge ditentukan oleh penerjemah ini . Dan salah satu "fitur" dari juru bahasa itu adalah bahwa ia mendorong nilai yang tidak ditentukan ke tumpukan untuk setiap loop dari playfield saat menjalankan program kosong. Diberi cukup waktu akhirnya akan kehabisan memori.

Seberapa cepat itu terjadi tergantung pada kecepatan komputer, memori yang tersedia, dan browser yang digunakan. Di komputer saya, saya menemukan bahwa Microsoft Edge bekerja paling baik, tetapi bahkan "hanya" menggunakan 500MB setelah dua menit. Tidak sampai sekitar tanda lima belas menit (dengan beberapa gigabyte digunakan) Edge memutuskan untuk membunuh proses dan menyegarkan tab. Jadi tidak mungkin untuk membuatnya di bawah batas waktu dua menit, tetapi dengan kondisi yang tepat yang belum tentu keluar dari pertanyaan.


8

SALAH, 8 byte

Saya sangat suka bahasa ini.

1[$][.]#

Ini mendorong a 1, lalu [$][.]#loop sementara $true (duplikat tumpukan) dan ( .) menampilkannya. Penerjemah ini lumpuh setelah 1cetakan tunggal (bukti loop berjalan setidaknya satu kali.) Tampaknya ada bug dalam penafsir ini. Program 9-byte berikut harus bekerja di semua penerjemah yang memenuhi syarat:

1[$][..]#

Anda juga harus mencoba DUP, yang pada dasarnya adalah superset dari FALSE. Itulah yang saya gunakan untuk membuat KEMBALI.
Mama Fun Roll

@MamaFunRoll oh yeah, saya lupa Anda membuat PENGEMBALIAN! Saya harus coba yang itu. : D
Conor O'Brien

@MamaFunRoll Saya suka DUP, saya baru saja menulis penerjemah DUP dan saya bermain-main dengannya.
ML

@ ConnorO'Brien: Saya akan mengatakan bahwa solusi pertama Anda harus membuat crash penerjemah mana pun. Saya baru saja menjalankan debug dengan juru bahasa saya sendiri, dan sudah jelas bahwa yang pertama .mengosongkan tumpukan data, sementara di loop kedua $mencoba untuk menduplikasi elemen atas tumpukan kosong, yang seharusnya mengarah pada kesalahan (well, penerjemah saya tidak ). Versi kedua tidak boleh valid karena bahkan tidak menyelesaikan loop pertama karena sudah mencoba mengakses tumpukan kosong sebelum waktunya.
ML

Untuk contoh kedua Anda, Berikut ini Dump debug berwarna penuh dari penerjemah DUP saya. sudah jelas setelah Anda melihat bagaimana tumpukan data (ds) dan tumpukan kembali (rs) bekerja, yang terakhir tidak transparan di SALAH, meskipun.
ML

8

C, 21 byte

i;f(){for(;1/!i++;);}

Di sini idijamin untuk memulai sebagai 0.

Dapat dikonfirmasi bahwa ini berjalan sekali seperti ini:

i;f(){for(;1/!i++;)puts("hi");}
main(){f();}

Yang, di mesin saya, menghasilkan:

llama@llama:...code/c/ppcg104323loop$ ./a.out 
hi
zsh: floating point exception (core dumped)  ./a.out

Solusi rekursif terpendek yang dapat saya temukan adalah 22 byte :

f(i){f(i-puts(""-i));}

gcchanya melakukan eliminasi panggilan ekor pada -O2atau lebih tinggi, pada titik mana kita perlu memanggil fungsi seperti putsuntuk mencegah semuanya dioptimalkan. Konfirmasi bahwa ini berfungsi:

llama@llama:...code/c/ppcg104323loop$ cat loop.c       
main(){f();}
f(i){f(i-puts(""-i));}
llama@llama:...code/c/ppcg104323loop$ gcc -O2 -S loop.c 2>/dev/null
llama@llama:...code/c/ppcg104323loop$ grep call loop.s
    call    puts
    call    f

Berikut ini adalah program lengkap, yang mengasumsikan bahwa ia dipanggil tanpa argumen baris perintah, sebesar 22 byte :

main(i){for(;1/i--;);}

yang setara dengan fungsi dengan panjang yang sama:

f(i){for(i=1;1/i--;);}

Apakah fungsi seperti ini diperlakukan seperti utama? Jika ya, argumen pertama adalah panjang dari daftar argumen (yaitu 1, nama yang dulu memanggilnya).
Riley

Atau, register argumen masih memiliki nilai yang ada dari main dipanggil.
Riley

@Riley Ahh, teori yang terakhir tampaknya menjadi kasusnya, sebagaimana dibuktikan oleh fakta bahwa jumlahnya meningkat ketika argumen baris perintah ditambahkan. Terima kasih atas wawasannya!
Gagang Pintu

Saya tidak yakin bagaimana Anda memanggilnya di tebakan pertama saya, tetapi saya harus sama dengan argumen pertama ke fungsi yang memanggil f.
Riley

Yap, tio
Riley

6

MATLAB, 18 byte

Ini dapat dijalankan sebagai skrip:

for j=1:2;j(j);end

Iterasi pertama baik-baik saja, karena j(1)itu adil 1. Iterasi kedua lumpuh dengan kesalahan array di luar batas, j(2)melebihi dimensi j, yang merupakan array 1x1.

Ini juga dapat dijalankan sebagai skrip, tetapi hanya berfungsi saat pertama kali Anda menjalankannya. Namun, itu adalah penyalahgunaan konstanta MATLAB yang cukup lucu yang saya pikir saya akan memasukkannya. Ini juga 18 byte.

while i/i;i={};end

Saat dijalankan di ruang kerja yang variabelnya ibelum didefinisikan, ini diasumsikan isebagai unit imajiner, jadi i/i = 1. Di loop pertama, tugas i={}membuat array sel kosong yang disebut i. Pada iterasi kedua, loop keluar dengan "Operator tidak ditentukan '/' untuk argumen input tipe 'sel'."


Keduanya luar biasa! Anda mungkin tahu ini, tetapi j(2)biasanya akan memberikan matriks 2-oleh-2 dengan0+1i
Stewie Griffin

Terima kasih! Itu benar dalam Oktaf tetapi tidak dalam MATLAB saya pikir
MattWH

6

Perl 6 , 13 byte

loop {5[$++]}

Mengindeks integer literal dalam infinite loop.
Bergantung pada fakta bahwa pada nilai skalar, sintaks pengindeksan array dapat digunakan dengan indeks 0(mengembalikan nilai itu sendiri), tetapi melemparkan Index out of rangekesalahan untuk indeks lainnya.


6

QBasic, 17 byte

Kode ini sangat aneh.

DO
i=11+a(i)
LOOP

Bagaimana itu bekerja

Dalam QBasic, variabel diinisialisasi. Variabel reguler tanpa akhiran tipe apa pun, seperti di isini, diinisialisasi ke nol.

Kecuali jika Anda mencoba untuk menyalin ke variabel itu seperti sebuah array ... dalam hal ini, itu adalah array dari 11 nol. *

Oleh karena itu, pertama kali melalui loop, iadalah 0dan amerupakan array. a(i)memberikan elemen nol dari array (yang 0). Semua baik dan bagus. Kami mengatur ike 11dan loop. Tapi sekarang 11bukan indeks yang valid untuk array a, dan program berhenti Subscript out of range.

Versi 19 byte yang lebih baik menunjukkan apa yang terjadi:

DO
?a(i)
i=i+1
LOOP

Ini akan mencetak 0sebelas kali sebelum kesalahan.


* Secara konseptual, ini adalah array 10 elemen. Sebagian besar hal dalam QBasic adalah 1-diindeks, tetapi array tidak, mungkin karena alasan implementasi. Untuk membuat segala sesuatunya berfungsi seperti yang diharapkan oleh para programmer, QBasic membuat entri tambahan sehingga Anda dapat menggunakan indeks 1 hingga 10. Namun indeks 0 masih dapat diakses dengan sempurna. Sosok pergi.


QBasic dan arrays, di mana kesenangan berhenti!
steenbergh

Karena kesalahan tidak harus berada pada loop kedua, tidak bisakah Anda melakukannya i=1+a(i)?
Quelklef

@Quelklef Tidak, Anda harus melakukannya i=i+1+a(i). Kalau tidak, indeks tidak akan pernah naik 1, yang bukan merupakan kesalahan.
DLosc

@ Docosc Oh, Anda benar.
Quelklef

5

Haskell, 15 byte

f(a:b)=f b
f"a"

f"a"berjalan secara rekursif melalui string "a" dengan menjatuhkan char pertama dan akhirnya gagal pada akhirnya dengan Non-exhaustive patterns in function fpengecualian, karena fhanya ditentukan untuk string yang tidak kosong.


5

C #, 71 38 byte

Karena Anda memberikan contoh dalam C # di sini versi lain golf

Dan terima kasih kepada pinkfloydx33

void c(){checked{for(uint i=1;;i--);}}

Lebih pendek daripada Parse.ToString()dan bahkan daripada yang Parse($"{c--}") saya buang secara mental checkedkarena kata kunci terlalu panjang. Sulit itu tentu saja lebih pendek dariParse(c.ToString())

Jawaban asli

class p{static void Main(){for(int c=0;;c--)uint.Parse(c.ToString());}}

Ini akan memulai c=0kemudian pengurangan itu, ketika c=-1para uint.Parseakan menyebabkan:

Unhandled Exception: System.OverflowException: Value was either too large or too small for a UInt32.

Versi tidak dikoleksi dan memverifikasi bahwa loop berjalan setidaknya sekali

class p {
    static void Main() {
        for(int c=0;;c--) {
            System.Console.Write(c);
            uint.Parse(c.ToString());
        }
    }
}

for(int c=0;;)uint.Parse($"{c--}");
pinkfloydx33

1
checked{for(uint c=1;;)c--;}
pinkfloydx33

Ok, wow! Tidak tahu tentang steno '$'!
MrPaulch

4

CJam , 4 byte

1{}g

Cobalah online!

Iterasi pertama dari {}gloop kosong muncul 1, yang memberitahu itu untuk melanjutkan. Iterasi kedua mencoba memunculkan kondisional lain, tetapi tumpukan kosong, sehingga program macet.


4

rakitan x86 (AT&T sintaks), 40 byte

f:
mov $1,%eax
A:
div %eax
dec %eax
je A

Deklarasikan fungsi f yang membagi 1 dengan 1 pada iterasi pertama kemudian mencoba untuk membagi 0 dengan 0 dan kesalahan.


Anda dapat menyimpan 4 byte dengan beralih ke sintaks Intel :)
mriklojn

6
Kami biasanya menilai perakitan dengan ukuran kode byte yang dihasilkan, bukan instruksi yang dapat dibaca manusia.
Dennis

@Dennis assmebled assembly adalah bahasa mesin. tapi ya ini bisa diklaim jauh lebih pendek dalam bentuk bahasa mesin.
Jasen

Singkirkan label-f dan mov. Tukar dec dan div, dan Anda dapat menyingkirkan lebih banyak lagi.
jelas

4

CJam, 4 byte

P`:~

P`menghasilkan string 3.141592653589793. :~mengevaluasi setiap karakter. 3adalah kode yang valid di CJam yang hanya mengembalikan 3. Dalam iterasi berikutnya, .menyebabkan kesalahan karena memerlukan angka atau operator yang mengikutinya.


4

Ruby, 14 Bytes

loop{$./=~$.}

Keluar karena ZeroDivisionError: divided by 0

$. The current input line number of the last file that was read

Ruby Docs



4

Batch, 22 20 byte

:a
set i=%i%1
goto a

Penjelasan

Ini adalah infinite loop yang menambahkan 1ke string yang awalnya kosong. Akhirnya ini akan melewati panjang string maksimum 8192 dan crash. Di komputer saya, ini membutuhkan waktu sekitar 30 detik.


Bagus! Anda dapat menyimpan 2 byte dengan menggunakan ujung garis Unix.
briantist

Anda dapat menggunakan% 0 yang merupakan nama file, bukan label dan goto.
YourDeathIsComing

Saya tidak yakin apakah itu melanggar aturan rekursi ekor.
SomethingDark

4

JavaScript, 9 byte

for(;;i);

Ini berjalan sekali, lalu melempar ReferenceError: i is not definedyang menghentikan loop.

// With a console.log(1) to see that it runs once.
for(;;i)console.log(1);


Mengambil contoh berikut, apakah <increment>akhir dari siklus pertama atau awal dari siklus kedua?

0:for(<init>;<test>;<increment>)
1:{
2:  <statement>;
3:}

1 / Aku melihatnya

Setelah berpindah dari baris 0 ke baris 3 lalu kembali ke baris 0, rasanya seperti siklus penuh telah selesai.
Itu akan <increment>menjadi awal dari siklus kedua.
- Siklus pertama: <init>-> <test>-> <statement>
- Siklus kedua: <increment>-> <test>-><statement>

2 / Whilesetara

0:<init>;
1:while(<test>)
2:{
3:  <statement>;
4:  <increment>;
5:}

Dalam setara ini whileyang <increment>adalah akhir dari siklus pertama dan rasanya seperti itu sama dengan for.
Itu akan membuat <increment>akhir dari siklus pertama.
- Siklus pertama: <test>-> <statement>-> <increment>
- Siklus kedua: <test>-> <statement>-><increment>

3 / Pernyataan dijumpai dua kali

Siklus penuh selesai ketika sebuah pernyataan dijumpai dua kali.
Pernyataan pertama yang ditemui dua kali adalah <test>.
Itu akan membuat <increment>akhir dari siklus pertama.
- Siklus pertama: <test>-> <statement>-> <increment>
- Siklus kedua: <test>-> <statement>-><increment>

4 / Ini pengaturan

The <init>hanya menyiapkan apa saja yang diperlukan untuk siklus pertama.
The <increment>hanya menyiapkan apa saja yang diperlukan untuk siklus kedua.
Itu akan <increment>menjadi awal dari siklus kedua.
- Siklus pertama: <init as a setup>-> <test>-> <statement>
- Siklus kedua: <increment as a setup>-> <test>-><statement>


Spesifikasi Bahasa ECMAScript® 2016

Runtime of for(<init>;<test>;<increment>)<statement>;

Biarkan varDcl menjadi hasil evaluasi <init>.
ReturnIfAbrupt (varDcl).
Kembali? ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelSet).

Ada tiga bentuk, jadi saya mengambil yang terpendek di sini, tidak ada perbedaan:
- Apapun <init>itu bukan bagian dari iterasi pertama.
- Apa yang relevan ada di ForBodyEvaluation.

Rincian ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelSet)

0 Biarkan V tidak terdefinisi.
1 Lakukan? CreatePerIterationEnvironment (perIterationBindings).
2 Ulangi
3 Jika tidak [kosong], maka
4 Biarkan testRef menjadi hasil evaluasi <test>.
5 Biarkan testValue menjadi? GetValue (testRef).
6 Jika ToBoolean (testValue) salah, kembalikan NormalCompletion (V).
7 Biarkan hasil menjadi hasil evaluasi <statement>.
8 Jika LoopContinues (hasil, labelSet) salah, kembalikan Penyelesaian (UpdateEmpty (hasil, V)).
9 Jika hasilnya. [[Nilai]] tidak kosong, misalkan V adalah hasil. [[Nilai]].
10 Lakukan? CreatePerIterationEnvironment (perIterationBindings).
11 Jika tidak [kosong], maka
12 Biarkan incRef menjadi hasil evaluasi <increment>.
13 Pertunjukan? GetValue (incRef).

6 / Aku melihatnya

Siklus penuh menjalankan penuh bagian berulang.
Itu akan membuat <increment>akhir dari siklus pertama.
- Siklus pertama: <test>-> <statement>-> <increment>/ Dengan kata lain dari baris 3 ke baris 13
- Siklus kedua: <test>-> <statement>-> <increment>/ Dengan kata lain dari baris 3 ke baris 13

7 / A cycle adalah iterasi

Sebuah siklus dimulai dengan CreatePerIterationEnvironment.
Jadi ketika CreatePerIterationEnvironmentditemui siklus baru dimulai, dengan demikian mengakhiri yang sebelumnya.
Itu akan <increment>menjadi awal dari siklus kedua.
- Siklus pertama: <test>-> <statement>/ Dengan kata lain dari baris 1 ke baris 9
- Siklus kedua: <increment>-> <test>-> <statement>/ Dengan kata lain dari perulangan baris 10 hingga baris 9


Apakah <increment>akhir dari siklus pertama atau awal dari siklus kedua?

Penjelasan yang benar adalah 6 atau 7.


8
Saya pikir saya lebih cenderung menganggap kenaikan ke akhir iterasi pertama, daripada ke awal iterasi kedua atau ke iterasi. Saya kira ini adalah ambiguitas pertanyaan.

1
Karena for(a;b;c)d;kira-kira setara dengan a;while(b){d;c;}, saya cenderung mengatakan bahwa kesalahan masih terlempar pada iterasi pertama (sebelum kondisi loop diperiksa untuk kedua kalinya).
ETHproductions

@Hurkyl Iterasi pertama dimulai dengan inisialisasi, jadi saya pikir kenaikan harus menjadi awal dari iterasi kedua.
Hedi

4
Jika Anda membaca spec , Anda dapat melihat bahwa operasi kenaikan adalah bagian terakhir dari iterasi dan karena itu, masih termasuk dalam iterasi pertama.
Nit

3
@Hedi saya tidak melihat bagaimana itu relevan sama sekali. Operasi kenaikan sangat jelas merupakan bagian dari putaran pertama loop. Untuk mengulangi, ketika operasi kenaikan dipanggil, loop belum selesai menjalankan penuh tunggal.
Nit

4

INTERCAL , 12 byte

(1)DO(1)NEXT

Cobalah online!

NEXTadalah perintah aliran kontrol utama INTERCAL-72. (Kemudian revisi diperkenalkan COME FROM, yang menjadi lebih terkenal, tetapi itu tidak ada dalam versi asli bahasa tersebut; dan semua implementasi INTERCAL yang telah selesai, saya menyadari dukungan NEXTuntuk kompatibilitas mundur, dengan semua kecuali satu yang memungkinkan dukungan untuk itu secara default. Jadi Saya tidak merasa perlu nama INTERCAL-72 khusus dalam judul.)

Saat menggunakan NEXTuntuk membentuk lingkaran, Anda seharusnya menggunakan RESUMEatau FORGETuntuk membebaskan ruang yang digunakan untuk mengingat di mana program telah; RESUMEsecara surut membuatnya NEXTmenjadi sesuatu yang mirip dengan pemanggilan fungsi (meskipun Anda dapat kembali dari fungsi selain yang Anda gunakan) sementara FORGETmembuatnya menjadi sesuatu yang lebih mirip dengan pernyataan GOTO. Jika Anda tidak melakukan keduanya (dan program ini tidak), program akan macet setelah 80 iterasi (perilaku ini sebenarnya ditentukan dalam spesifikasi INTERCAL).

Agak ambigu apakah ini dianggap sebagai rekursi yang tidak terikat (tidak diizinkan dalam pertanyaan); Anda tentu saja dapat menggunakan semacam ini NEXTuntuk mengimplementasikan pemanggilan fungsi, yang dalam hal ini akan secara efektif menjadi fungsi rekursif, tetapi tidak ada informasi yang cukup di sini untuk menentukan apakah kita melakukan pemanggilan fungsi atau tidak. Setidaknya, saya tetap memposting ini karena tidak melanggar aturan, dan implementasi INTERCAL yang mengoptimalkan "tail call" tidak hanya akan melanggar spesifikasi, tetapi juga menyebabkan sebagian besar program yang ada rusak, karena kembali dari "fungsi yang salah" adalah cara utama untuk melakukan yang setara dengan pernyataan IF.

Inilah pesan kesalahan yang dihasilkan, seperti yang dihasilkan oleh C-INTERCAL:

ICL123I PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON
    ON THE WAY TO 1
        CORRECT SOURCE AND RESUBNIT

(Perhatikan bahwa baris kedua diindentasi dengan tab, dan yang ketiga dengan delapan spasi. Ini terlihat benar di terminal, atau di hampir semua program yang memiliki penghentian tab pada kelipatan 8. Namun, Penurunan harga memiliki penghentian tab di kelipatan dari empat, melanggar asumsi yang dibuat oleh kebanyakan program yang lebih lama tentang tab, jadi pesan kesalahannya sedikit salah format di sini.)


Apakah kesalahan itu benar-benar dikatakan CORRECT SOURCE AND RESUBNIT? Seperti dalam salah ketik pada pesan kesalahan C-INTERCAL asli?
Andrakis

1
@ Andrakis: Ya, benar. Kesalahan ketik itu telah dipertahankan dengan hati-hati selama bertahun-tahun.

3

Pyth, 3 byte

W1w

Cobalah online.

W1hanya while 1:dengan Python. Badan loop mencetak baris yang dibaca dari STDIN, yang macet untuk iterasi kedua ketika kode dijalankan dengan input kosong.

Jika loop menggunakan #(loop-hingga-error) dilarang (saya berasumsi demikian), saya pikir ini adalah yang terpendek yang bisa didapat.


3

Python 3, 29 byte

i=1
def x(n):del i;x(i)
x(i)

Sangat sederhana. Pada panggilan kedua ke x, saya tidak ada di sana, dan Python mengeluh tentang hal itu.


3

Labirin , 3 byte

#(/

Cobalah online!

Seperti kebanyakan bahasa 2D, Labyrinth tidak memiliki konstruksi perulangan eksplisit. Sebaliknya, kode apa pun yang ditata sedemikian rupa sehingga dijalankan beberapa kali berturut-turut adalah loop dalam bahasa-bahasa ini. Untuk kasus Labyrinth, program linier sederhana bertindak sebagai loop, karena penunjuk instruksi akan memantul ke sana kemari. Jika programnya adalah abc(untuk beberapa perintah a, bdan c), maka eksekusi yang sebenarnya akan abcbabcbabcb...berjalan abcbdi infinite loop.

Adapun mengapa program khusus ini crash pada iterasi kedua dari loop ini, di sini adalah apa yang dilakukan perintah individu. Perhatikan bahwa tumpukan Labyrinth berisi jumlah nol tak terbatas yang tersirat di bagian bawah:

#   Push stack depth.   [... 0]
(   Decrement.          [... -1]
/   Divide.             [... 0]
(   Decrement.          [... -1]
#   Push stack depth.   [... -1 1]
(   Decrement.          [... -1 0]
/   Divide.             Crashes with division-by-zero error.

3

Bash, 11 (Borderline tidak bersaing)

exec $0 1$@

Script ini secara rekursif mengeksekusi dirinya sendiri, menambahkan 1argumen yang diteruskan pada setiap iterasi. Saya pikir ini dianggap sebagai TCO karena exec menggunakan kembali ruang proses tetapi tidak memakan tumpukan. Ini adalah batas yang tidak bersaing karena butuh sekitar 10 menit sebelum terbunuh di mesin saya - YMMV.


1
exec $0 1$@$@ berakhir jauh lebih cepat tetapi dua karakter lebih lama.
Jasen

3

cmd, 34 byte

for /l %i in (0,1,10) do color %i0

Ini akan menggilir %idari 0 hingga 10. Perintah (kuno) colorakan dengan senang hati menerima argumen apa pun yang memiliki 2 (hexa) angka desimal. Dengan argumen 100itu akan gagal, mencetak pesan bantuan dan pengaturan ERRORLEVELke 1.

Bukti loop berjalan setidaknya sekali: Warna shell Anda akan berbeda!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.