Kürzeste selbstzerstörende Schleife


61

Ihre Aufgabe ist es, ein vollständiges Programm oder eine Funktion zu schreiben , die keine Eingabe nimmt und führen jede Art von Schleife ( while, for, foreach, do, do-while, do-loop, goto, Rekursion, usw.) , die bei der Verursachung einen Fehlers enden wird, was bedeutet , dass das Programm anhalten muss dich läuft und Ausfahrt.

Regeln:

  1. Der Fehler muss ein Laufzeitfehler, eine nicht behandelte Ausnahme oder alles sein, was das Programm selbst beenden lässt.
  2. Der Fehler muss zum Beenden und Beenden des Programms führen, ohne dass exit;irgendwann ein expliziter (oder gleichwertiger) Aufruf erfolgt .
  3. Nachrichten wie Warning:, Notice:, usw., die das Programm nicht dazu führen , dass sich am Ende sind nicht gültig. Beispielsweise wird in PHP-Divisionen durch Null eine WarningMeldung ausgegeben, das Programm wird jedoch nicht angehalten und weiterhin ausgeführt. Dies ist keine gültige Antwort.
  4. Die Schleife muss mindestens einen vollen Zyklus durchlaufen. Mit anderen Worten, der Fehler kann ab dem zweiten Zyklus und darüber hinaus auftreten. Dies soll verhindern, dass der Fehler durch falsche Codesyntax verursacht wird: Der Code muss syntaktisch korrekt sein.
  5. Die Schleife kann sogar unendlich sein (Beispiel for(;;);), wenn die oben genannten Regeln eingehalten werden. Es darf jedoch nicht länger als 2 Minuten dauern, bis ein Laufzeitfehler auftritt.
  6. Rekursion ohne Tail Call-Optimierung ist ungültig ( 1 , 2 ).
  7. Das ist also gewinnt der kürzeste Code.
  8. Standardlücken sind verboten.

C # -Beispiel ( Online-Test ):

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

Bestenliste:

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>

Vielen Dank an Martin Ender für das Leaderboard Snippet


Nur um klar zu sein, kann eine Rekursion ohne TCO verwendet werden, solange der Fehler nicht mit zu viel Rekursion zu tun hat, richtig? (Zum Beispiel eine rekursive Funktion, die bei der zweiten Rekursion Fehler macht)
ETHproductions

@ETHproductions Dennis schlug im Chat vor: "In diesem Fall ist es möglicherweise schwierig zu entscheiden, ob ein vollständiger Zyklus abgeschlossen ist. Die Schwanzrekursion passt irgendwie in die Rechnung, aber nur die Gesamtbetriebskosten schließen einen Zyklus tatsächlich ab, wenn die Ausführung abgebrochen wird durch einen Fehler. [...] Ich würde sagen, Rekursion ohne TCO ist ungültig. "
Mario

In for(a;b;c)d;, nach welcher Aussage endet der erste Zyklus? Ist es gültig, bei der ersten Bewertung der cAussage zu brechen ?
Hedi

1
@Hedi Hier ist meine bescheidene Meinung (nicht das OP): Alle Einträge müssen einen vollständigen Zyklus durchlaufen, dh sie müssen in einen zweiten Zyklus eintreten ; Dies bedeutet, dass mindestens eine Anweisung ein zweites Mal ausgeführt wird. Da die Reihenfolge der Ausführung in Ihrem Beispiel ist a, b, d, c, b, d, c, ..., bist der Beginn des Zyklus, und muss mindestens ein zweites Mal ausgeführt werden.
ETHproductions

2
Ich möchte keinen Ärger machen, aber da das (eigentlich funktionsfähige) Programm keine Eingaben machen soll, sind alle rekursiven Lösungen mit einem Parameter ungültig, da ein Parameter eingegeben wird.
BrainStone

Antworten:


33

MATL , 5 1 Byte

Idee aus @ MartinEnders CJam-Antwort

`

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

Alte Version

2:t"x

Probieren Sie es 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
Funktioniert auch offline. Keine Eingabe bedeutet, dass Sie eine leere Eingabe annehmen können.
Dennis

@Dennis Hm, das Offline-Programm wartet weiterhin auf Benutzereingaben. Die Eingabe erfolgt interaktiv, dh bei Bedarf in der Offline-Version angefordert. Das Programm wird also auf unbestimmte Zeit warten. Nicht sicher, ob das zählt?
Luis Mendo

Wir sind uns nicht ganz sicher, wie MATL intern funktioniert, aber wenn Sie es in einer Umgebung ausführen, die keine Eingaben anfordern kann (z. B. im Backend von TIO), kann es keine Eingaben abrufen. Außerdem sollte das Drücken von Strg-D oder dem vom Betriebssystem abhängigen Äquivalent erlaubt sein, leere Eingaben zu senden.
Dennis

35

Python, 16 Bytes

Der nicht interessante 0-Teilungsansatz:

for x in 1,0:x/x

Die erste Iteration berechnet 1 / 1, was gut funktioniert. Die zweite Iteration versucht zu berechnen 0 / 0, was zu einem ZeroDivisionErrorAuslösen führt.

17 Bytes (persönlicher Favorit)

i=1
while i:del i

Anfangs, i=1was wahr ist, wird also die Schleife betreten.

Beim ersten Ausführen der Schleife wird die Variable igelöscht.

Dies bedeutet, dass es sich beim zweiten Mal inicht mehr um eine Variable handelt und daher deren Auswertung mit fehlschlägtNameError: name 'i' is not defined.


Eine weitere 15-Byte-Lösung wäre def _():_()(newline) _(), da Python die Schwanzrekursion nicht optimiert. Dies verstößt jedoch gegen Regel 6.


Die 17 Bytes Lösung funktioniert auch , wenn Sie ersetzen while imit , while 1weil sie zu löschen versucht , iwieder;
user6245072

2
@ user6245072 yep, beide Schnipsel können für viele Arbeitslösungen einfach modifiziert werden
FlipTack

Sie können Ihren verwenden del: Trick mit einem eingebauten in abrasieren ein paar mehr while 1:del id.
DSM


18

Gelee , 3 2 Bytes

Ṿß

Tötet sich selbst, indem der Speicher knapp wird. Dies geschieht lokal nach ~ 100 Sekunden.

Probieren Sie es online! (Sterbeurkunde in der Debug- Schublade)

Wie es funktioniert

Ṿß  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.

Die ersten paar Iterationen ergeben:

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

Danach wird es sehr hässlich, sehr schnell.


Was sind die Gedächtnisgrenzen von Gelee?
Tuskiomi

Jelly hat keine explizite Speicherbeschränkung, was auch immer Python ansprechen kann. Die Speichernutzung verdoppelt sich jedoch mit jeder Iteration, sodass der gesamte verfügbare Speicher ziemlich schnell erschöpft sein sollte.
Dennis

28
Alle 2 Jahre können wir eine weitere Iteration ausführen
tuskiomi

Scheitert also die Bedingung Nr. 5 auf langsamen Rechnern mit viel RAM?
Mad Physicist

@ MadPhysicist Das ist richtig. Dies ist jedoch ein inhärentes Problem mit Zeitlimits. Die Konformität hängt stark davon ab, auf welchem ​​Computer das Programm ausgeführt wird.
Dennis

13

V , 2 Bytes

òl

Probieren Sie es online!

Dies ist die perfekte Herausforderung für V, weil ich das schon die ganze Zeit mache! Tatsächlich hat V nicht einmal Bedingungen, sondern nur Funktionen, die bei einem Fehler abbrechen. In diesem Fall òbedeutet "für immer wiederholen" und l"nach rechts bewegen".

In einem leeren Puffer (keine Eingabe) wird dies beim ersten Durchlauf unterbrochen und keine Ausgabe erzeugt. Wenn es eine Eingabe gibt, bricht diese ab, sobald wir das letzte Zeichen der Eingabe eingeben und die gesamte Eingabe ausgeben (was dies auch zu einem Katzenprogramm macht).


3
Warten Sie, lbedeutet "nach rechts bewegen"? Nicht " left bewegen "?
Conor O'Brien

1
@ ConorO'Brien yep. Es gibt tatsächlich einige gute historische Gründe dafür.
DJMcMayhem

3
Die Herausforderung erfordert Antworten, die bei der zweiten oder späteren Iteration abstürzen, nicht bei der ersten Iteration.
Martin Ender

11

JavaScript (ES6), 13 Byte

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

Dies ist eine rekursive Funktion, die einmal ausgeführt, dann ausgelöst ReferenceError: a is not definedund beendet wird.

Hier ist eine 15-Byte-Version ohne ES6:

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

Dies läuft einmal gut, wirft dann TypeError: i is undefinedund beendet.


10

Bash 4.2, 22 Bytes

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

Funktioniert nicht in TIO, da es Bash 4.3 enthält und der Fehler, auf den ich mich verlasse, endlich behoben wurde.

Nachprüfung

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

Dies stürzt ab, sobald das Programm versucht, 2 63 mod -1 zu berechnen , was in Bash 4.2 und älteren Versionen aufgrund eines bekannten Fehlers abstürzt.


10

PHP, 22 21 20 18 Bytes

Dies beruht auf PHP, das es einem erlaubt, einer Variablen einen Funktionsnamen zu geben und zu versuchen, sie auszuführen.

Dadurch wird der Name der piFunktion einfach zweimal verkettet . Dies tötet PHP mit einem Fatal Error: Uncaught Error: Call to undefined function pipi() in [...][...].

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

Das funktioniert ähnlich wie bei meiner alten Antwort.


Alte Antwort, 20 Bytes

Mit PHP können Sie Zeichen mit dem Inkrement-Operator inkrementieren. Es funktioniert nur auf der a-zStrecke, ist aber genug.

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

Ich glaube, dass dies alle erforderlichen Punkte erfüllt und die Schleife einmal ausgeführt wird.

Sie können sehen, ob Sie den Fehler erhalten Fatal error: Function name must be a string.


So geht's Schritt für Schritt:

  • Zuweisen pizu $x.
    Da pies als Konstante verwendet wird, prüft PHP, ob es existiert.
    Da dies nicht der Fall ist, zeigt PHP einen Warnhinweis an. Use of undefined constant pi - assumed 'pi'(Grundsätzlich gilt: Da die Konstante nicht existiert, wird angenommen, dass es sich um eine Zeichenfolge handelt.)
  • Schleife das erste Mal
    • Führen Sie die Funktion aus $x().
      Da $xhat den Wert pi, wird es die Funktion ausführen pi().
  • Speichern Sie den Wert in $x.
    $xhat jetzt π stattpi
  • Schleife zum zweiten Mal
    • Führen Sie die Funktion aus $x().
      Da $xπ hat, wird die Funktion ausgeführt 3.14159...().
    • π ist keine Zeichenkette und beendet das Programm an dieser Stelle mit a Fatal Error.

Vielen Dank an @Titus für das Auffinden der pi()Funktion, die mir 1 Byte erspart hat !


Schön, aber ich glaube nicht, dass es gültig ist. Es läuft nicht wirklich die Schleife einmal. Sie erhöhen $xauf, abtbevor der Schleifenkörper ausgeführt wird. Sie können dies beheben, indem Sie nach der Schleife inkrementieren .
am

Ich dachte an einen anderen Ansatz
etwa

@aross Duh, du hast recht, es war nicht gültig. Das Inkrement befindet sich an der falschen Stelle. Es funktioniert so, wie es jetzt sein sollte. Sie können versuchen, for($x=abs;;++$x)echo$x,$x();zum Testen auszuführen . Es sollte sich zeigen abs0abt Fatal error[...]. Oder ähnliches.
Ismael Miguel

1
Sie könnten pianstelle von verwenden abs. Das bringt nicht einmal eine Warnung, bevor es den Tod auslöst.
Titus

@Titus Ich habe diese Funktion komplett vergessen! Ich weiß, dass die Funktion _in einigen Systemen definiert ist, aber unzuverlässig ist. Aber danke, dass du das gefunden hast!
Ismael Miguel

10

GNU sed , 15 13 5 Bytes

-2 Dank Seshoumara
-8 Dank Zeppelin

H;G;D
  1. Fügt eine neue Zeile und den Haltebereich an den Musterbereich an.
  2. Fügt eine neue Zeile und den Musterbereich an den Haltebereich an.
  3. Löscht bis zur ersten Zeile und beginnt von vorne.

Das hat schnell keinen Speicher mehr:

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

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

Hallo, wie wäre es s:a\?:&a:g? Es ist 1 Byte kleiner und verdoppelt auch die Mustergröße pro Iteration.
Seshoumara

@seshoumara Ich glaube nicht, dass das mit etwas übereinstimmt, wenn der Musterbereich leer ist, daher wird es niemals den ersten Ersatz geben.
Riley

@seshoumara echo -n | sed 's:a\?:&a:g'und bekam keine Ausgabe. Es wäre dasselbe wie sed 's::a:'das, was zu nichts passen würde.
Riley

Mit echo -nabsolut nichts wird an sed übergeben, aber sed kann nicht ohne Eingabe von Design starten. Überprüfen Sie diesen Meta-Link, um festzustellen, ob dies echo|sedder akzeptierte Weg ist, um sed für Herausforderungen zu starten, die eine Regel ohne Eingabe aufrufen.
Seshoumara

@seshoumara Ich dachte, es würde immer noch eine leere Zeichenfolge geben. Das scheint dann zu funktionieren. Vielen Dank!
Riley

9

R, 22 25 22 20 18 Bytes

Edit: Vielen Dank an @Mego für den Hinweis, dass R die Tail-Call-Optimierung nicht unterstützt.

Edit4: Habe eine noch kürzere Lösung gefunden, die einfach und doch recht kompliziert ist.

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

Die Antwort verwendet die eingebaute boolesche Wahrheitsvariable, Tdie in der Wiederholungsschleife auf unbestimmte Zeit dekrementiert wird. Die Funktion ls()heißt jede Iteration, die alle Objekte in der aktuellen Umgebung auflistet. Das erste Argument namegibt jedoch an, aus welcher Umgebung Objekte aufgelistet werden sollen. Aus der R-Dokumentation entnehmen wir:

Das Argument name kann die Umgebung angeben, aus der Objektnamen in einer von mehreren Formen übernommen werden: als Ganzzahl (die Position in der searchListe); als Zeichenkettenname eines Elements in der Suchliste; oder als explizite environment(einschließlich der Verwendung, sys.frameum auf die aktuell aktiven Funktionsaufrufe zuzugreifen).

Dies bedeutet hauptsächlich, dass wir in der ersten Iteration ls(-1)das zurückgeben würden character(0)(Standard, wenn versucht wird, auf das nicht vorhandene everything-except-the-firstElement eines beliebigen Zeichentypobjekts zuzugreifen ). Während der zweiten Iteration Twird um zwei dekrementiert und anschließend aufgerufen, ls(-3)was wiederum den Fehler zurückgibt:

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

Dies liegt daran, dass wir versuchen, ein everything-except-the-thirdElement aufzulisten, die lokale Umgebung jedoch nur die Variable Tzu diesem Zeitpunkt enthält ( ls()wodurch 1bei dieser Iteration eine Liste mit der Länge zurückgegeben wird), und ein Fehler zurückgegeben wird.


1
Das hört sich nicht so an, als würde die Rekursion mit der Tail-Call-Optimierung durchgeführt, wenn es ein Rekursionslimit gibt.
Mego

@Mego Nach einigem Herumstöbern stellte ich fest, dass R in der Tat keine Tail-Call-Optimierung unterstützt, sodass diese Antwort nicht gültig ist (noch nie von dem Konzept gehört). Wird gleich zu einer gültigen Antwort.
Billywob

9

Befunge-93, 3 Bytes (möglicherweise 1 oder 0)

!%!

Probieren Sie es online!

Bei der ersten Iteration der Schleife ist der Stapel leer, was allen Nullen entspricht. Die !(Nicht) -Operation wandelt somit den Stapelanfang in 1 um, und die %(Modulo) -Operation berechnet 0 mod 1, wobei 0 übrig bleibt. Die nächste !Operation wandelt diese 0 in eine 1 um, bevor der Programmzähler einen Zeilenumbruch vornimmt und die Schleife erneut beginnt.

Bei der zweiten Iteration !konvertieren die ersten Operationen die 1, die sich jetzt oben auf dem Stapel befindet, in eine 0. Die %Operation berechnet dann 0 mod 0, wodurch im Referenzinterpreter ein Fehler durch Null dividiert wird, und beendet somit das Programm.

Es gibt auch die langweiligere 1-Byte-Antwort, obwohl ich nicht sicher bin, ob dies als gültig angesehen wird.

"

Probieren Sie es online!

Dieser "Befehl startet eine Zeichenkette, daher wird jedes Leerzeichen in der restlichen Zeile auf den Stapel geschoben, bis der Programmzähler auf das "erneute Schließen der Zeichenkette stößt . Es muss dann ein zweites Mal gewickelt werden, um den Vorgang zu wiederholen, indem eine weitere Zeichenfolge gestartet und weitere 79 Leerzeichen auf den Stapel geschoben werden. Letztendlich wird entweder der Arbeitsspeicher knapp (das Verhalten des Referenzinterpreters) oder ein Stapelüberlauf erzeugt.

Wenn Sie die Regeln wirklich durchsetzen möchten, gibt es auch technisch eine Null-Byte-Lösung.


Wenn Sie diese Regel so verstehen, dass jeder Dolmetscher die Sprache definiert (wie viele hier), können wir für den Moment davon ausgehen, dass die Befunge-Sprache von diesem Dolmetscher definiert wird . Und eines der "Merkmale" dieses Interpreters ist, dass er bei der Ausführung eines leeren Programms für jede Schleife des Spielfelds einen undefinierten Wert auf den Stapel legt. Wenn genügend Zeit zur Verfügung steht, wird der Arbeitsspeicher irgendwann ausgehen.

Wie schnell dies geschieht, hängt von der Geschwindigkeit des Computers, dem verfügbaren Speicher und dem verwendeten Browser ab. Auf meinem Computer hat Microsoft Edge am besten funktioniert, aber selbst dann waren nach zwei Minuten "nur" 500 MB belegt. Es dauerte ungefähr eine Viertelstunde, bis Edge entschied, den Vorgang abzubrechen und die Registerkarte zu aktualisieren. Es ist also unwahrscheinlich, dass es unter dem Zeitlimit von zwei Minuten gelingt, aber unter den richtigen Bedingungen, die nicht unbedingt in Frage kommen.


8

FALSE, 8 Bytes

Ich mag diese Sprache wirklich.

1[$][.]#

Dies drückt a 1und [$][.]#schleift dann , solange $es wahr ist (Stapelanfang duplizieren) und ( .) gibt es aus. Dieser Interpreter stürzt ab, nachdem die Single 1gedruckt wurde (Beweis dafür, dass die Schleife mindestens einmal ausgeführt wird). Es scheint ein Fehler in diesem Interpreter zu sein. Das folgende 9-Byte-Programm sollte in allen kompatiblen Interpretern funktionieren:

1[$][..]#

Sie sollten auch DUP ausprobieren, was im Grunde eine Obermenge von FALSE ist. Genau das habe ich bei RETURN gemacht.
Mama Fun Roll

@MamaFunRoll oh yeah, ich habe vergessen, dass du RETURN gemacht hast! Ich muss es versuchen. : D
Conor O'Brien

@MamaFunRoll Ich liebe DUP, ich habe gerade einen DUP-Interpreter geschrieben und spiele damit herum.
ML

@ConnorO'Brien: Ich würde sagen, dass deine erste Lösung jeden Interpreter zum Absturz bringen sollte. Ich habe gerade einen Debug-Lauf mit meinem eigenen Interpreter durchgeführt, und es ist offensichtlich, dass der erste .den Datenstapel leert, während in der zweiten Schleife $versucht wird, das oberste Element des leeren Stapels zu duplizieren, was zu einem Fehler führen sollte (nun, mein Interpreter tut dies) ). Die zweite Version sollte nicht gültig sein, da sie nicht einmal die erste Schleife beendet, da sie bereits versucht, vorzeitig auf den leeren Stapel zuzugreifen.
ML

Für Ihr zweites Beispiel ist hier ein vollfarbiger Debug-Dump meines DUP-Interpreters. Es ist offensichtlich, wie der Datenstapel (ds) und der Rückgabestapel (rs) funktionieren. Letzterer ist jedoch in FALSE nicht transparent.
ML

8

C, 21 Bytes

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

Hier ifängt garantiert an wie 0.

Es kann bestätigt werden, dass dies einmal so läuft:

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

Was auf meinem Rechner zur Folge hat:

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

Die kürzeste rekursive Lösung, die ich finden kann, ist 22 Bytes :

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

gccerst ab Tail Call Elimination -O2müssen wir eine Funktion aufrufen puts, um zu verhindern, dass das Ganze wegoptimiert wird. Bestätigung, dass dies funktioniert:

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

Das folgende Programm ist vollständig und setzt voraus, dass es mit 22 Byte ohne Befehlszeilenargumente aufgerufen wird :

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

das ist gleichbedeutend mit der Funktion der gleichen Länge:

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

Wird eine Funktion wie diese wie main behandelt? Wenn dies der Fall ist, gibt das erste Argument die Länge der Argumentliste an (dies ist 1, der Name, der zum Aufrufen verwendet wurde).
Riley

Oder das Argumentregister hat immer noch den Wert, der beim Aufruf von main vorhanden war.
Riley

@ Riley Ahh, die letztere Theorie scheint der Fall zu sein, was durch die Tatsache belegt wird, dass die Anzahl steigt, wenn Befehlszeilenargumente hinzugefügt werden. Danke für den Einblick!
Türklinke

Ich war mir bei meiner ersten Vermutung nicht sicher, wie Sie es nennen, aber ich sollte das gleiche sein wie das erste Argument für die Funktion, die f aufruft.
Riley

Ja, tio
Riley

6

MATLAB, 18 Bytes

Dies kann als Skript ausgeführt werden:

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

Die erste Iteration ist in Ordnung, da j(1)ist gerade 1. Die zweite Iteration stürzt mit einem außerhalb der Grenzen liegenden Fehler ab, der j(2)die Abmessungen jeines 1x1-Arrays überschreitet .

Dies kann auch als Skript ausgeführt werden, funktioniert jedoch nur, wenn Sie es zum ersten Mal ausführen. Trotzdem ist es witzig genug, die vordefinierten Konstanten von MATLAB zu missbrauchen, so dass ich dachte, ich würde es einschließen. Es sind auch 18 Bytes.

while i/i;i={};end

Beim Ausführen in einem Arbeitsbereich, in dem die Variable inoch nicht definiert wurde, wird davon iausgegangen, dass es sich um die imaginäre Einheit handelt i/i = 1. In der ersten Schleife wird durch die Zuweisung i={}ein leeres Zellenfeld mit dem Namen erstellt i. Bei der zweiten Iteration wird die Schleife mit "Undefinierter Operator '/' für Eingabeargumente vom Typ 'Zelle'" beendet.


Beide sind großartig! Sie wissen das wahrscheinlich, aber j(2)normalerweise erhalten Sie eine 2-mal-2-Matrix mit0+1i
Stewie Griffin

Vielen Dank! Das stimmt in Octave, aber nicht in MATLAB, denke ich
MattWH

6

Perl 6 , 13 Bytes

loop {5[$++]}

Indiziert ein Integer-Literal in einer Endlosschleife.
Beruht auf der Tatsache, dass bei skalaren Werten die Array-Indizierungssyntax mit index verwendet werden kann 0(wobei der Wert selbst zurückgegeben wird), aber Index out of rangefür jeden anderen Index ein Fehler ausgegeben wird.


6

QBasic, 17 Bytes

Dieser Code ist sehr seltsam.

DO
i=11+a(i)
LOOP

Wie es funktioniert

In QBasic werden Variablen vorinitialisiert. Eine reguläre Variable ohne iTypenzusatz wird wie hier auf Null vorinitialisiert.

Es sei denn, Sie versuchen, diese Variable wie ein Array zu subskribieren. In diesem Fall handelt es sich um ein Array mit 11 Nullen. *

Auf das erste Mal durch die Schleife daher iist 0und aist ein Array. a(i)gibt das nullte Element des Arrays an (welches ist 0). Alles schön und gut. Wir machen ieine 11Schleife. Aber jetzt 11ist kein gültiger Index für das Array a, und das Programm stoppt mit Subscript out of range.

Eine 19-Byte-Version, die besser zeigt, was los ist:

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

Dies wird 0elf Mal gedruckt, bevor ein Fehler auftritt.


* Konzeptionell handelt es sich um ein Array mit 10 Elementen. Die meisten Dinge in QBasic sind 1-indiziert, Arrays jedoch nicht, möglicherweise aus Implementierungsgründen. Damit die Dinge für Programmierer wie erwartet funktionieren, wirft QBasic einen zusätzlichen Eintrag ein, sodass Sie die Indizes 1 bis 10 verwenden können. Auf Index 0 kann jedoch weiterhin problemlos zugegriffen werden. Stelle dir das vor.


QBasic und Arrays, wo hört der Spaß auf!
Steenbergh

Da der Fehler nicht haben auf der zweiten Schleife sein, konnte nicht tun Sie i=1+a(i)?
Quelklef

@Quelklef Nein, das müsstest du tun i=i+1+a(i). Andernfalls wird der Index nie höher 1, was kein Fehler ist.
DLosc

@ DLosc Oh, du hast recht.
Quelklef

5

Haskell, 15 Bytes

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

f"a"Läuft rekursiv durch die Zeichenfolge "a", indem das erste Zeichen gelöscht wird, und schlägt schließlich mit einer Non-exhaustive patterns in function fAusnahme am Ende fehl , da dies fnur für nicht leere Zeichenfolgen definiert ist.


5

C #, 71 38 Bytes

Da Sie in C # ein Beispiel angegeben haben, hat hier eine andere Version Golf gespielt

Und danke an pinkfloydx33

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

Kürzer als Parse.ToString()und sogar als Parse($"{c--}") ich checkedes mir in den Kopf gesetzt habe, weil es ein zu langes Schlüsselwort war. Tough ist es sicherlich kürzer alsParse(c.ToString())

Ursprüngliche Antwort

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

Dies startet c=0und dekrementiert es dann, wenn c=-1das uint.Parseein verursacht:

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

Ungolfed-Version und Überprüfung dieser Schleife läuft mindestens einmal

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 Wussten Sie nicht über die Abkürzung "$"!
MrPaulch

4

CJam , 4 Bytes

1{}g

Probieren Sie es online!

Bei der ersten Iteration der leeren {}gSchleife wird die eingeblendet 1, die angibt , dass fortgefahren werden soll. Bei der zweiten Iteration wird versucht, eine andere Bedingung einzufügen, aber der Stapel ist leer, sodass das Programm abstürzt.


4

x86-Assembly (AT & T-Syntax), 40 Byte

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

Deklariert eine Funktion f, die bei ihrer ersten Iteration 1 durch 1 teilt und dann versucht, 0 durch 0 und Fehler zu teilen.


Sie können 4 Bytes sparen, indem Sie zur Intel-Syntax
wechseln

6
Wir bewerten Assemblierung normalerweise anhand der Größe des generierten Bytecodes, nicht anhand der von Menschen lesbaren Anweisungen.
Dennis

@Dennis Assmebled Assembly ist Maschinensprache. aber ja, dies könnte in maschinensprachlicher Form viel kürzer behauptet werden.
Jasen

Werde das f-Etikett und den mov los. Tauschen Sie dec und div aus, und Sie können noch mehr loswerden.
Klarer

4

CJam, 4 Bytes

P`:~

P`generiert den String 3.141592653589793. :~wertet jedes Zeichen aus. 3ist ein gültiger Code in CJam, der einfach 3 zurückgibt. .Verursacht in der nächsten Iteration einen Fehler, da eine Ziffer oder ein darauf folgender Operator erforderlich ist.


4

Rubin, 14 Bytes

loop{$./=~$.}

Ausgänge wegen ZeroDivisionError: divided by 0

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

Ruby Docs



4

Batch, 22 20 Bytes

:a
set i=%i%1
goto a

Erläuterung

Dies ist eine Endlosschleife, die 1ein anfangs leeres Zeichen anhängt . Letztendlich wird dies die maximale Stringlänge von 8192 überschreiten und abstürzen. Auf meinem Computer dauert dies ungefähr 30 Sekunden.


Nett! Sie können 2 Bytes sparen, indem Sie Unix-Zeilenenden verwenden.
Briantist

Sie können% 0 als Dateinamen anstelle von label und goto verwenden.
YourDeathIsComing

Ich war mir nicht sicher, ob dies gegen die Schwanzrekursionsregel verstößt.
SomethingDark

4

JavaScript, 9 Bytes

for(;;i);

Dieser läuft einmal und wirft dann, ReferenceError: i is not definedwas die Schleife stoppt.

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


Ist das <increment>Ende des ersten Zyklus oder der Beginn des zweiten Zyklus am Beispiel des Folgenden ?

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

Ich sehe es

Nach dem Wechsel von Zeile 0 zu Zeile 3 und dann zurück zu Zeile 0 fühlt es sich an, als wäre ein vollständiger Zyklus abgeschlossen.
Das wäre <increment>der Beginn des zweiten Zyklus.
- Erster Zyklus: <init>-> <test>-> <statement>
- Zweiter Zyklus: <increment>-> <test>-><statement>

2 / WhileÄquivalent

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

In diesem Ersatz whiledas <increment>ist das Ende des ersten Zyklus und es fühlt sich an wie es das gleiche mit dem ist for.
Das wäre <increment>das Ende des ersten Zyklus.
- Erster Zyklus: <test>-> <statement>-> <increment>
- Zweiter Zyklus: <test>-> <statement>-><increment>

3 / Eine Anweisung wird zweimal angetroffen

Ein vollständiger Zyklus ist abgeschlossen, wenn eine Anweisung zweimal auftritt.
Die erste Anweisung, die zweimal vorkommt, lautet <test>.
Das wäre <increment>das Ende des ersten Zyklus.
- Erster Zyklus: <test>-> <statement>-> <increment>
- Zweiter Zyklus: <test>-> <statement>-><increment>

4 / Es ist ein Setup

Sie <init>richten nur das ein, was für den ersten Zyklus benötigt wird.
Sie <increment>richten nur das ein, was für den zweiten Zyklus benötigt wird.
Das wäre <increment>der Beginn des zweiten Zyklus.
- Erster Zyklus: <init as a setup>-> <test>-> <statement>
- Zweiter Zyklus: <increment as a setup>-> <test>-><statement>


Die ECMAScript® 2016-Sprachspezifikation

Laufzeit von for(<init>;<test>;<increment>)<statement>;

Sei varDcl das Ergebnis der Auswertung <init>.
ReturnIfAbrupt (varDcl).
Rückkehr ? ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelset).

Es gibt drei Formen, also habe ich die kürzeste hier genommen, es gibt keinen Unterschied:
- Was auch immer, <init>es ist nicht Teil der ersten Iteration.
- Was relevant ist, ist in ForBodyEvaluation.

Details von ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelset)

0 Sei V undefiniert.
1 Durchführen? CreatePerIterationEnvironment (perIterationBindings).
2 Wiederholen
3 Wenn nicht [leer], dann
4 testRef sei das Ergebnis der Auswertung <test>.
5 Lass testValue sein? GetValue (testRef).
6 Wenn ToBoolean (testValue) false ist, geben Sie NormalCompletion (V) zurück.
7 Das Ergebnis sei das Ergebnis der Bewertung <statement>.
8 Wenn LoopContinues (result, labelSet) false ist, geben Sie Completion (UpdateEmpty (result, V)) zurück.
9 Wenn result. [[Value]] nicht leer ist, sei V result. [[Value]].
10 Durchführen? CreatePerIterationEnvironment (perIterationBindings).
11 Wenn nicht [leer] ist, dann
12 Sei incRef das Ergebnis der Auswertung <increment>.
13 Durchführen? GetValue (incRef).

6 / Ich sehe es

Ein vollständiger Zyklus Ein vollständiger Lauf des Wiederholungsteils.
Das wäre <increment>das Ende des ersten Zyklus.
- Erster Zyklus: <test>-> <statement>-> <increment>/ Mit anderen Worten von Zeile 3 bis Zeile 13
- Zweiter Zyklus: <test>-> <statement>-> <increment>/ Mit anderen Worten von Zeile 3 bis Zeile 13

7 / Ein Zyklus ist eine Iteration

Ein Zyklus beginnt mit CreatePerIterationEnvironment.
Wenn CreatePerIterationEnvironmentalso ein neuer Zyklus angetroffen wird, beginnt dieser und beendet den vorherigen.
Das wäre <increment>der Beginn des zweiten Zyklus.
- Erster Zyklus: <test>-> <statement>/ Mit anderen Worten von Zeile 1 bis Zeile 9
- Zweiter Zyklus: <increment>-> <test>-> <statement>/ Mit anderen Worten von Zeile 10 bis Zeile 9 durchlaufen


Ist das <increment>das Ende des ersten Zyklus oder der Beginn des zweiten Zyklus?

Die richtige Erklärung ist entweder 6 oder 7.


8
Ich glaube, ich bin eher geneigt, das Inkrement dem Ende der ersten Iteration zuzuschreiben, als dem Anfang der zweiten Iteration oder keiner der beiden Iterationen. Ich nehme an, das ist eine Mehrdeutigkeit der Frage.

1
Da for(a;b;c)d;ist in etwa gleichbedeutend mit a;while(b){d;c;}, ich bin geneigt zu sagen, dass der Fehler immer noch in der ersten Iteration ausgelöst wird (bevor die Schleifenbedingung ein zweites Mal überprüft wird).
ETHproductions

@Hurkyl Die erste Iteration beginnt mit der Initialisierung, daher denke ich, dass das Inkrement der Beginn der zweiten Iteration sein sollte.
Hedi

4
Wenn Sie die Spezifikation lesen , können Sie sehen, dass die Inkrementierungsoperation der letzte Teil der Iteration ist und als solche immer noch zur ersten Iteration gehört.
Nit

3
@Hedi Ich sehe nicht, wie das überhaupt relevant ist. Die Inkrementierungsoperation ist ganz klar ein Teil des ersten Durchlaufs der Schleife. Zum Umformulieren hat die Schleife beim Aufrufen der Inkrementierungsoperation noch keinen vollständigen Durchlauf beendet.
Nit

4

INTERCAL , 12 Bytes

(1)DO(1)NEXT

Probieren Sie es online!

NEXTist der Hauptsteuerflussbefehl von INTERCAL-72. (Spätere Revisionen wurden eingeführt COME FROM, die bekannter wurden, aber nicht in der Originalversion der Sprache vorhanden waren. Alle abgeschlossenen INTERCAL-Implementierungen unterstützen die NEXTAbwärtskompatibilität, alle bis auf eine unterstützen sie standardmäßig. Also Ich habe nicht das Bedürfnis, INTERCAL-72 speziell im Titel zu nennen.)

Wenn Sie NEXTzum Bilden einer Schleife verwenden, müssen Sie RESUMEoder FORGETverwenden, um den Speicherplatz freizugeben, der verwendet wird, um sich daran zu erinnern, wo sich das Programm befunden hat. RESUMEmacht das rückwirkend NEXTzu etwas, das einem Funktionsaufruf ähnelt (obwohl Sie von anderen Funktionen als der, in der Sie sich befinden, zurückkehren können), während FORGETes zu etwas macht, das einer GOTO-Anweisung ähnlicher ist. Wenn Sie dies auch nicht tun (und dieses Programm nicht), stürzt das Programm nach 80 Iterationen ab (dieses Verhalten ist tatsächlich in der INTERCAL-Spezifikation angegeben).

Es ist etwas mehrdeutig, ob dies als unbegrenzte Rekursion gilt (in der Frage nicht zulässig); Sie können diese Art sicherlich verwenden NEXT, um einen Funktionsaufruf zu implementieren. In diesem Fall handelt es sich effektiv um eine rekursive Funktion, aber hier sind nicht genügend Informationen vorhanden, um zu bestimmen, ob ein Funktionsaufruf ausgeführt wird oder nicht. Zumindest poste ich dies trotzdem, weil es nicht eindeutig gegen die Regeln verstößt und eine INTERCAL-Implementierung, die den "Tail Call" optimiert, nicht nur gegen die Spezifikation verstößt, sondern auch die meisten existierenden Programme zum Absturz bringt, weil sie von zurückkehren Die "falsche Funktion" ist die Hauptmethode, um das Äquivalent einer IF-Anweisung zu erreichen.

Hier ist die resultierende Fehlermeldung, die von C-INTERCAL generiert wurde:

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

(Beachten Sie, dass die zweite Zeile mit einem Tabulator eingerückt ist und die dritte mit acht Leerzeichen. Dies sieht in einem Terminal oder in so ziemlich jedem Programm, das Tabulatoren bei Vielfachen von 8 hat, korrekt aus. Markdown hat jedoch Tabulatoren bei Vielfachen von viertens, was gegen die Annahmen verstößt, die die meisten älteren Programme in Bezug auf Tabulatoren vertreten, so dass die Fehlermeldung hier etwas falsch formatiert ist.)


Sagt der Fehler wirklich CORRECT SOURCE AND RESUBNIT? Wie in einem Tippfehler in der ursprünglichen C-INTERCAL-Fehlermeldung?
Andrakis

1
@ Andrakis: Ja, das tut es. Dieser Tippfehler wurde jahrelang sorgfältig aufbewahrt.

3

Pyth, 3 Bytes

W1w

Probieren Sie es online aus.

W1ist nur while 1:in Python. Der Schleifenkörper gibt eine aus STDIN gelesene Zeile aus, die bei der zweiten Iteration abstürzt, wenn der Code mit leerer Eingabe ausgeführt wird.

Wenn Schleifen mit #(loop-until-error) gesperrt sind (ich nehme an), denke ich, dass dies die kürzeste ist, die es bekommen kann.


3

Python 3, 29 Bytes

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

Ganz einfach. Beim zweiten Aufruf von x bin ich nicht da und Python beschwert sich darüber.


3

Labyrinth , 3 Bytes

#(/

Probieren Sie es online!

Wie die meisten 2D-Sprachen hat Labyrinth keine expliziten Schleifenkonstrukte. Stattdessen ist jeder Code, der so angeordnet ist, dass er mehrmals hintereinander ausgeführt wird, eine Schleife in diesen Sprachen. Für den Fall von Labyrinth fungiert ein einfaches lineares Programm als Schleife, da der Befehlszeiger darauf hin und her springt. Wenn das Programm abc(für einige Befehle a, bund c), dann die tatsächliche Ausführung wird abcbabcbabcb...so läuft es abcbin einer Endlosschleife.

Warum dieses spezielle Programm bei der zweiten Iteration dieser Schleife abstürzt, erfahren Sie in den einzelnen Befehlen. Beachten Sie, dass der Labyrinth-Stapel unten eine implizite unendliche Anzahl von Nullen enthält:

#   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 nicht konkurrierend)

exec $0 1$@

Dieses Skript wird rekursiv von selbst ausgeführt und 1an die bei jeder Iteration übergebenen Argumente angehängt. Ich denke, dies zählt als Gesamtbetriebskosten (TCO), da Exec den Prozessraum wiederverwendet, aber keinen Stapel auffrisst. Es ist grenzwertig nicht konkurrierend, da es ungefähr 10 Minuten gedauert hat, bis es auf meiner Maschine - YMMV - getötet wurde.


1
exec $0 1$@$@ endet viel schneller, ist aber zwei Zeichen länger.
Jasen

3

cmd, 34 bytes

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

Dies wechselt %izwischen 0 und 10. Der (alte) colorBefehl akzeptiert gerne alle Argumente mit 2 (hexa-) Dezimalstellen. Mit dem Argument schlägt 100es fehl, die Hilfemeldung zu drucken und ERRORLEVELauf 1 zu setzen.

Beweis, dass die Schleife mindestens einmal läuft: Die Farbe Ihrer Muschel wird anders sein!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.