Schauen wir uns eine typische Schleife an, die normalerweise 8 Iterationen durchführt:
for (int x=0; x<8; ++x);
Du musst es unendlich machen!
Es ist ein Beliebtheitswettbewerb für alle Sprachen, die eine solche Art von for
Schleife unterstützen. Also gewinnt die Lösung mit der höchsten Punktzahl (Upvotes minus Downvotes).
Wenn Ihre Sprache die andere Form der for
Schleife hat, Sie sich aber sicher sind, können Sie damit etwas Cooles machen, die Antwort gerne posten und als nicht konkurrierend markieren. Ich behalte mir das Recht vor, den Umfang der verfügbaren Konstruktionen und Sprachen zu vergrößern, er wird jedoch niemals verkleinert, sodass Sie keine Angst haben, zuvor korrekte Lösungen zu verwerfen.
Was ist eine Lösung?
Lösung besteht aus zwei Programmen.
Das erste Programm ist ein sauberes Programm. Dies ist das typische Programm in Ihrer Sprache, bei dem die for
Schleife 8 Iterationen durchführt. Es sollte das normale Programm sein, das jeder Entwickler schreiben könnte. Keine speziellen Hacks für Vorbereitungszwecke. Beispielsweise:
int main()
{
for (int x=0; x<8; ++x);
return 0;
}
Das zweite Programm wird erweitert. Dieses Programm sollte den gesamten Code aus dem bereinigten Programm und zusätzlichen Code enthalten. Es gibt nur eine begrenzte Anzahl von Erweiterungspunkten. Weitere Informationen finden Sie im Abschnitt zu den vollständigen Regeln. Ein erweitertes Programm für das obige Clean kann sein
inline bool operator < (const int &a, const int &b)
{
return true;
}
int main()
{
for (int x=0; x<8; ++x);
return 0;
}
Das ist nur ein Beispiel (in C ++ nicht kompilierbar), um eine Idee zu zeigen. Das wirklich korrekte erweiterte Programm muss kompilierbar sein, funktionieren und eine Endlosschleife haben.
Regeln vervollständigen
Beide Programme:
- Jede Sprache, die solche
for
Schleifen unterstützt, ist in Ordnung. - Der Schleifenkörper muss leer sein. Genauer gesagt, Sie können eine Ausgabe oder einen anderen Code in die Schleife einfügen, aber das Verhalten der Schleife sollte im Fall einer leeren Schleife gleich sein.
Sauberes Programm:
Die Schleife verwendet einen ganzzahligen oder numerischen Zähler und führt 8 Iterationen durch:
for (int x=0; x<8; ++x); // C, C++, C# for (var x=0; x<8; ++x); // C#, Javascript for (auto x=0; x<8; ++x); // C, C++ for (auto signed x=0; x<8; ++x); // C, C++ for (register int x=0; x<8; ++x); // C, C++
Benutzerdefinierte Typen sind nicht zulässig.
- Die Verwendung von Eigenschaften (außer globalen Variablen) anstelle von Schleifenvariablen ist nicht zulässig.
Die Variablendeklaration kann innerhalb oder außerhalb der Schleife erfolgen. Folgender Code ist in Ordnung:
int x; for(x=0; x<8; ++x);
Es kann entweder ein Präfix- oder ein Postfix-Inkrement verwendet werden.
Das Schleifenlimit
8
sollte als konstantes Literal geschrieben werden, ohne dass es in einer benannten Konstante oder Variablen gespeichert wird. Es wurde entwickelt, um Lösungen zu verhindern, die darauf beruhen, dass eine Variable oder Konstante mit dem Wert 8 deklariert und dann durch den anderen Wert neu zugewiesen, überschrieben oder abgeschattet wird:const double n = 8; int main() { const double n = 9007199254740992; for (double x=0; x<n; ++x); return 0; }
Erweitertes Programm:
- Muss den gesamten Code des sauberen enthalten.
- Sollte sauberes Programm in begrenzter Anzahl von Erweiterungspunkten verlängern.
- Muss dieselbe
for
Schleife wie eine Endlosschleife selbst ausführen .
Das Platzieren der Schleife in einer anderen unendlichen Konstruktion ist nicht in Ordnung. - Das Patchen des Codes zur Laufzeit oder zur Kompilierungszeit ist zulässig, solange die Textdarstellung unverändert bleibt.
- Das Einfügen der Konstruktion in eine Zeichenfolge und das Weitergeben an
eval
ist nicht zulässig.
Erweiterungspunkte:
- Überall außerhalb des Fragments mit sauberem Code, einschließlich anderer Dateien oder anderer Assemblys.
for
Anweisung (als Einzelstück -for
Konstruktion und sein Körper) muss unverändert bleiben.- Die Variablendeklaration muss gleich bleiben.
- Jeder Punkt zwischen einfachen Anweisungen kann als Erweiterungspunkt verwendet werden.
- Wenn und nur wenn die Variable außerhalb der Schleife und ohne sofortige Zuweisung des Werts deklariert wurde, kann eine solche Zuweisung hinzugefügt werden.
/* extension point here */
int main()
/* extension point here */
{
/* extension point here */
int x /* extension point for assignment here */;
/* extension point here */
for (x=0; x<8; ++x);
/* extension point here */
return 0;
/* extension point here */
}
/* extension point here */
int main()
{
/* BEGIN: No changes allowed */ int x = 0; /* END */
/* extension point here */
/* BEGIN: No changes allowed */ for (x=0; x<8; ++x); /* END */
return 0;
}
PS: Stellen Sie nach Möglichkeit einen Link zur Online-IDE bereit.
java.lang.Integer
? 2. Dies wäre besser mit einem richtigen Gewinnkriterium.Antworten:
Python3
Reinigungsprogramm:
Dies ist nur eine Standard-Countdown-While-Schleife.
Erweitertes Programm:
Es verwendet den int-Cache zum Neudefinieren
8
, wie9
die effektiv die machtn -= 1
einen no-op, seit9-1 = 8
dem gerade setzt ,n
um wieder9
einmal die unendliche Schleife verursacht.Sie können den int-Cache online in Aktion sehen hier sehen (allerdings offensichtlich ohne die Endlosschleife, da sie online ist).
quelle
8
zu9
Python 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Python 3
Reinigungsprogramm:
Die Standardmethode, um in Python 8-mal etwas zu tun, ist:
Erweitertes Programm:
Wenn wir jedoch die Bereichsgeneratorfunktion überschreiben, um unendlich 1 zu ergeben, wird sie zu einer Endlosschleife ...
Wir können dies weiterführen und eine Generatorfunktion erstellen, die nicht unendlich viel 1 ergibt, sondern für immer zählt:
Test auf repl.it
quelle
Perl
Reinigen
Erweitert
Ideone .
quelle
$i
soll ein Alias für eine spezielle Variable werden, die nur Boolesche Werte enthalten kann. Sobald es 1 erreicht, kann es nicht mehr inkrementiert werden.ES5 + (Javascript)
BEARBEITEN : Die explizite Variablendeklaration wurde entfernt, da sie ansonsten angehoben und eine nicht konfigurierbare window.x- Eigenschaft erstellt wurde (es sei denn, sie wird zeilenweise in der REPL-Konsole ausgeführt).
Erläuterung:
Nutzt die Tatsache aus, dass jede Variable mit globalem Gültigkeitsbereich auch eine Eigenschaft des window- Objekts ist, und definiert die Eigenschaft "window.x" so, dass sie den konstanten Wert 1 hat.
Reinigen
Erweitert
HINWEIS : Damit dies in Node.js funktioniert, ersetzen Sie einfach "window" durch "global" (getestet in Node.js 6.8.0).
quelle
var
in Crome. Aber Sie könnenvar
beide Programme entfernen - es wird in Ordnung sein.var
Hebezeuge, daher ist im Moment der BenutzungdefineProperty
bereits Schluss. Wenn Sie diese beiden Zeilen jedoch in verschiedenen Skripten platzieren (es ist übrigens zulässig), funktioniert dies, da die Eigenschaft zuerst erstellt undvar
dann ignoriert wird. Beweis: i.stack.imgur.com/lSwbE.pngC
Programm reinigen
Erweitertes Programm
quelle
Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok.
Java
Sauberes Programm:
Erweitertes Programm:
Legt die Ganzzahl im Ganzzahl-Cache fest, die 1 bis 0 enthalten soll, und bewirkt, dass
i++
nichts unternommen wird (sie setzti
auf die zwischengespeicherte Ganzzahl, die 1 enthalten soll, aber da diese Ganzzahl tatsächlich 0 enthält, ändert sich nichts).quelle
int
eher das Unboxed als das relativ Heavyweight verwenden würdeInteger
.C ++
bool
kann nur 0 oder 1 sein. Inspiriert von der Perl-Antwort von primo .quelle
Python 3 (3.5.0)
Reinigungsprogramm:
Erweitert
Diese Lösung unterscheidet sich von den anderen in Python geschriebenen insofern, als sie den Quellcode im laufenden Betrieb ändert. Alle Elemente in der for-Schleife können in den gewünschten Code geändert werden.
Der Code ändert den vorletzten Opcode so, dass
113
er lesbarer oder besser lesbar istJUMP_ABSOLUTE
. Er ändert den Operanden in160
den Befehl, an dem die for-Schleife beginnt, und erstellt am Ende des Programms eine GOTO-Anweisung.Das erweiterte Programm druckt die Zahlen
0..7
unendlich oft ohne Stapelüberlauf oder ähnliches.quelle
PHP
Ich denke, dies folgt den Regeln für Erweiterungspunkte. Ich bin mir in Punkt 4 nicht ganz sicher. Es ist sehr ähnlich zu @ primos Perl-Antwort, also denke ich, dass es zählt.
Reinigen
Erweitert
Mit PHP können Sie bestimmte Zeichenfolgen wie folgt inkrementieren:
Alle diese Zeichenfolgen werden mit 0 ausgewertet, sodass sie praktisch für immer in einer Schleife ablaufen (es sei denn, der Speicher geht irgendwie zur Neige).
quelle
Perl
Code bereinigen
Erweiterter Code
Die meisten Perl-Variablen sind nur Variablen. Die Sprache verfügt jedoch auch über eine
tie
Funktion, mit der Sie Variablen Getters und Setters effektiv zuweisen können. In diesem Programm mache ich das Hauptpaket (dessen Name die Nullzeichenfolge ist) zum Äquivalent einer Klasse aus einer objektorientierten Sprache, während es gleichzeitig ein Programm sein soll. Dadurch kann ich denfor
Schleifenzähler mit dem Programm selbst verknüpfen. Das Implementieren vonTIESCALAR
allow hat keine Auswirkung, und Leseversuche geben immer einen Wert von weniger als 8 zurück.tie
Erfolg; Der Rückgabewert von WertTIESCALAR
soll ein Verweis auf jeden internen Zustand sein, den wir mit der Variablen verknüpfen müssen. Da wir jedoch keinen benötigen, geben wir einen leeren Array-Verweis als Platzhalter zurück. Wir geben dann die einfachstmöglichen Implementierungen von Getter und Setter an. Keiner von beiden tut etwas, also versucht er es zuzuweisen$x
undef
quelle
WinDbg
Reinigen
Erweitert
Bei diesem Ansatz wird ein Alias für
<
as erstellt|
. Wenn<
also im Code ein Alias gefunden wird, wird dieser auf|
und bitweise erweitert - oder wird anstelle von less than ausgeführt. In WinDbg sind alle Nicht-Null-Werte wahr, alsoanything | 8
immer wahr.Hinweis: Das
.block
wird nicht benötigt, wenn dasaS
und.for
tatsächlich wie hier gezeigt als zwei verschiedene Zeilen eingegeben werden. Es wird nur benötigt, wenn sich dasaS
und.for
in derselben Zeile befinden.quelle
Mathematica
Reinigen
Erweitert
quelle
Common Lisp
Code bereinigen
Erweitert
Es wird ein Makro mit dem Namen
keyword:dotimes
aka:dotimes
(siehe 11.1.2.3 Das KEYWORD-Paket ) definiert, das sich als Endlosschleife erweitert. Dasdefmacro
Makro gibt den Namen des zu definierenden Makros zurück, der weitergeleitet werden kannshadowing-import
. Dieses neuedotimes
Symbol gibt dem Standard einen Schatten (der in tragbaren Programmen nicht neu definiert oder lexikalisch an ein anderes Makro gebunden werden sollte).Augmented (2)
Wenn wir das Zeichen 8 lesen, ersetzen wir es durch
(loop)
. Dies bedeutet, dass das oben Gesagte wie folgt lautet(dotimes (i (loop)))
und der Code daher die Berechnung der Obergrenze niemals beendet. Dies wirkt sich auf alle Vorkommen von 8 aus, nicht nur auf das Vorkommen in der Schleife. Mit anderen Worten, 8 steht wirklich für Unendlichkeit. Wenn Sie neugierig sind und die Lesetabelle wie oben geändert wird, wird das Zeichen 8 "terminierend" und löst sich von anderen Zahlen / Symbolen, die gerade gelesen werden:... lautet wie folgt:
Sie können Tests auf Ideone ausführen: https://ideone.com/sR3AiU .
quelle
Rubin
Reinigen
Diese Art von for-Schleife wird in Ruby nicht häufig verwendet, aber ein typisches Tutorial zeigt Ihnen, dass dies die richtige Vorgehensweise ist:
Erweitert
Die for-Schleife ruft nur
(1..8).each
den angegebenen Codeblock auf, daher ändern wir diese Methode:quelle
Haskell
Saubere Version:
Erweiterte Version:
Es ist recht einfach, wirklich: wir unsere eigene Art nur definieren ,
T
so dass seineenumFromTo
Instanz eine unendliche Folge ist, dann Typ verwenden säumige so , dass die UN-Typ-kommentierten Werte0
und8
werden als Typ genommenT
.quelle
///
Es gibt keine expliziten
for
Schleifen in ///, sie können aber simuliert werden (es ist schließlich komplett).Reinigen:
Erweitert:
Was ist los?
Während das erste Programm von 8 auf 0 herunterzählt, zählt das zweite
/0/0/
Regel ersetzt0
durch0
bis in alle Ewigkeit.quelle
/0/1//1/2/.../7/8//8/8/8
stattdessen etwas tun würdest, um hoch zu zählen.Javascript ES6
OK, hier ist eine Version, die mit dem ES6 for ... of-Schleifenkonstrukt funktioniert. Ich werde Ihnen sogar ein sauberes Array geben, damit wir sicher sind, dass es keine lustigen Geschäfte gibt:
Reinigen
Das hindert natürlich niemanden daran, sich mit dem Array-Prototypen herumzuschlagen ...
Erweitert
Dies funktioniert, indem der Standard-Iterator überschrieben wird, sodass er niemals beendet wird, wodurch alles in eine Endlosschleife eingeschlossen wird. Der Code hat nicht einmal die Chance, das Zeug in der Schleife laufen zu lassen.
quelle
var
in der Schleife zulassen.C ++
Verwendet 2 Erweiterungspunkte:
Das Reinigungsprogramm ist dasselbe wie in der Beschreibung.
quelle
Brainfuck
Ich gebe bei jeder Iteration eine 0 aus, um das Zählen von Iterationen zu vereinfachen. Aber jeder Code könnte dort eingefügt werden, ohne die Funktionsweise der Schleife zu ändern.
Reinigen
Probieren Sie es online aus
Die erweiterte Version basiert auf der üblichen Brainfuck-Implementierung mit 8-Bit-Zellen. In diesen Implementierungen ist "Inkrement" tatsächlich "Inkrement (Mod 256)". Um also eine Schleife zu finden, die in der sauberen Version genau achtmal und in der erweiterten Version endlos iteriert, können wir einfach eine Lösung für das folgende Ungleichungssystem finden.
In diesem Fall lassen wir a = 128, b = 16 und c = 1. Offensichtlich sind 128 + 16 * 8 = 256 (und 256 (mod 256) = 0) und 128> 0, und da b gerade ist, ist c + a + b * n ist ungerade für jedes ungerade a + c und wird in solchen Fällen niemals ein gerades Vielfaches von 256 sein. Der Einfachheit halber wählen wir c = 1. Die einzige Änderung, die wir brauchen, ist also eine einzige
+
am Anfang des Programms.Erweitert
Probieren Sie es online aus
Ich überlasse es dem OP zu bestimmen, ob dieser Eintrag konkurriert. Brainfuck hat keine explizite for-Schleife, aber die von mir verwendete Schleifenform ist so nah wie möglich.
++++++++
ist auch so nah an einem wörtlichen8
wie Sie bekommen können; Ich habe einige davon aufgenommen.Die bereinigte Version stellt mit ziemlicher Sicherheit ein typisches Programm in dieser Sprache dar, da selbst die kürzeste bekannte Brainfuck Hello World von einer modularen Wiederholungsbeziehung zur Arbeit abhängt.
quelle
Haskell
Reinigen
Erweitert
Ersetzt den normalen Funktionsanwendungsoperator
$
durch einen, der die Schleife bei jedem Abschluss erneut wiederholt. Das Ausführen der sauberen Version gibt 0 bis 8 aus und stoppt dann; Die erweiterte Version gibt 0 bis 8 und dann wieder 0 bis 8 aus und so weiter.Ich schummle ein bisschen, das
forM_ [0..8] $ \i -> print i
ist nicht unbedingt die "sauberste" Art, diese Schleife in Haskell zu schreiben. Viele Haskeller würden den Schleifenkörper eta-reduzieren, um ihn zu bekommen,forM_ [0..8] print
und dann gibt es keinen Grund$
zum Überschreiben. Zu meiner Verteidigung habe ich den sauberen Code aus der Antwort von Cactus kopiert , der diese Eigenschaft nicht benötigte. Daher hat mindestens ein Haskell-Programmierer diesen Code tatsächlich geschrieben, ohne die Motivation, den Code unnötig hinzuzufügen$
!quelle
C ++
Lässt sich
x
zu 7 auswerten. Funktioniert nicht in C, da es einen Wert bei Zuweisung und Inkrementierung erfordert.quelle
Nim
Die idiomatische Version mit
countup
:Reinigen
Erweitert
Einfach und sehr ähnlich der Python-Antwort, die neu definiert wird
range
. Wir definierencountup
die idiomatische Nim-Methode, um von einem int (einschließlich) zum nächsten zu wechseln und 8s unendlich zu geben.Die interessantere Version mit dem Bereichsoperator
..
:Reinigen
Erweitert
Sehr ähnlich der vorherigen Lösung, außer dass wir den Bereichsoperator
..
, der normalerweise ein Array ergibt[1, 2, 3, 4, 5, 6, 7, 8]
, für den Iterator von zuvor neu definieren.quelle
GolfScript
Reinigen
Erweitert
Es weist der Variablen 8 die Funktion zu, die n + 1 zurückgibt
quelle
tcl
Normal:
Erweitert:
Die Idee ist, den
incr
Befehl, der zum Inkrementieren der Variablen verwendet wirdi
, so zu definieren , dass er tatsächlich nicht inkrementiert wird!Kann getestet werden unter: http://rextester.com/live/QSKZPQ49822
quelle
x86_64-Assembly
Sauberes Programm:
Die Art von Schleife, die ein Assembly-Programmierer verwenden würde, gefolgt von einem Exit-Systemaufruf, um anschließend keine
jmp loop_start
Anweisung hinzufügen zu können .Erweitertes Programm:
Es tut uns auch leid, wenn es schlecht ist, dass das Clean-Programm keinen Entropoint oder keinen hat
section .text
quelle
JavaScript
Reinigen:
Erweitert:
quelle
C ++
Programm reinigen
Eine schöne, normale Schleife, die von 0 bis 7 durchläuft.
Erweitertes Programm
Der Präprozessor von C ++ ist eine ziemlich gefährliche Funktion ...
Die einzige Zeile, die wir hinzufügen mussten, war
#define short bool
. Dies machti
einen Booleschen Wert anstelle einer kurzen Ganzzahl, und der Inkrementoperator (i++
) führt nachi
Erreichen von 1 nichts aus . Die Ausgabe sieht dann folgendermaßen aus:quelle