8 sollte Unendlichkeit werden


19

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 für alle Sprachen, die eine solche Art von forSchleife unterstützen. Also gewinnt die Lösung mit der höchsten Punktzahl (Upvotes minus Downvotes).

Wenn Ihre Sprache die andere Form der forSchleife 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 forSchleife 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 forSchleifen 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 8sollte 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 evalist nicht zulässig.

Erweiterungspunkte:

  • Überall außerhalb des Fragments mit sauberem Code, einschließlich anderer Dateien oder anderer Assemblys.
  • forAnweisung (als Einzelstück - forKonstruktion 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.


2
@Oliver, wie ich weiß, "höchste Punktzahl (Upvotes minus Downvotes)" ist genau die Vorgabe für einen Beliebtheitswettbewerb , zumindest steht in der Beschreibung des Tags: "Ein Beliebtheitswettbewerb ist ein Wettbewerb, bei dem die Antwort mit der höchsten Stimmenzahl übereinstimmt (Upvotes minus Downvotes) gewinnt. " Aber ich kann es explizit zu der Frage hinzufügen.
Qwertiy

1
@Maltysen, es gibt viele interessante Lösungen für Sprachen mit dieser Konstruktion. Es gibt C und C ++ (mit absolut unterschiedlichen Lösungen), C #, Java, Javascript, PHP, Perl, Groovy. Ich bin mir sicher, dass es noch viel mehr gibt. Jedenfalls bin ich offen, Fragen zu vergrößern und das ist in Regeln festgelegt. Wenn Sie etwas Iterestes in einer anderen Sprache erstellen können, posten Sie es. Wenn es positive Auswirkungen hat, können die Regeln erweitert werden.
Qwertiy

4
Dies als Beliebtheitswettbewerb zu tun ist etwas umständlich, da es keine Beschreibung gibt, welche Kriterien die Wähler bei der Abstimmung auswählen sollten (was die Siegbedingung subjektiv macht). Ich habe an einer Code-Golf- Lösung gearbeitet, auf der Basis, dass viele Leute hier Golf-Lösungen interessant finden und sie daher möglicherweise beliebt sind. das scheint eine brauchbare Siegbedingung für die Herausforderung zu sein.

2
1. " Ganzzahliger oder numerischer Zähler " ist etwas zu vage. ZB beinhaltet es java.lang.Integer? 2. Dies wäre besser mit einem richtigen Gewinnkriterium.
Peter Taylor

1
1. Ja, das tut es. 2. Was genau sind die Erfolgskriterien? PS: Wir können mit Meta weitermachen .
Qwertiy

Antworten:


33

Python3

Reinigungsprogramm:

Dies ist nur eine Standard-Countdown-While-Schleife.

n = 8
while n != 0:
  n -= 1
print("done")

Erweitertes Programm:

import ctypes

ctypes.cast(id(8), ctypes.POINTER(ctypes.c_int))[6] = 9

n = 8
while n != 0:
  n -= 1
print("done")

Es verwendet den int-Cache zum Neudefinieren 8 , wie 9die effektiv die macht n -= 1einen no-op, seit 9-1 = 8dem gerade setzt , num wieder 9einmal 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).


Könnten Sie bitte einen Link zu onlinde IDE bereitstellen? ideone.com/aI3ZrI - scheint dort nicht zu funktionieren.
Qwertiy

@Qwertiy, ich habe versucht, es in repl.it auszuführen, aber es friert nur ein, was zu erwarten ist, da es eine Endlosschleife sein wird. Ich weiß , das int - Cache Zeug funktioniert es, weil das ist , wo ich mit , wie man Satz experimentiert 8zu9
Maltysen

Funktioniert wirklich dort. Seltsam, dass du kein Zeitlimit wie Ideone hast (5 Sek.). Sie zeigenPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy

@Qwertiy Link ohne die Schleife: repl.it/E4fx/0
Maltysen

Das ist interessant ...
Qwertiy

22

Python 3

Reinigungsprogramm:

Die Standardmethode, um in Python 8-mal etwas zu tun, ist:

for i in range(8): 
    # Do something
    pass

Erweitertes Programm:

Wenn wir jedoch die Bereichsgeneratorfunktion überschreiben, um unendlich 1 zu ergeben, wird sie zu einer Endlosschleife ...

def range(x):
    while 1: yield 1

for i in range(8):
    # Infinite loop
    pass

Wir können dies weiterführen und eine Generatorfunktion erstellen, die nicht unendlich viel 1 ergibt, sondern für immer zählt:

def range(x):
    i = 0
    while 1: yield i; i+=1

for i in range(8):
    # Counting from 0 to infinity
    pass

Test auf repl.it


2
Verstecken Sie das in der Mitte eines riesigen Moduls ...
Benjamin

21

Perl

Reinigen

for($i=0; $i<8; $i++) { }

Erweitert

*i=*|;
for($i=0; $i<8; $i++) { }

Ideone .


16
Oh, das ist wirklich klug. Für alle, die Perl nicht kennen: Dieses Alias $isoll ein Alias ​​für eine spezielle Variable werden, die nur Boolesche Werte enthalten kann. Sobald es 1 erreicht, kann es nicht mehr inkrementiert werden.

10

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

for(x=0; x<8; x+=1) console.log(x);

Erweitert

Object.defineProperty(window,'x',{value:1});
for(x=0; x<8; x+=1) console.log(x);

HINWEIS : Damit dies in Node.js funktioniert, ersetzen Sie einfach "window" durch "global" (getestet in Node.js 6.8.0).


1
Übrigens ist es ES5, nicht wahr?
Qwertiy

Auch funktioniert es nicht mit varin Crome. Aber Sie können varbeide Programme entfernen - es wird in Ordnung sein.
Qwertiy

@Qwertiy das funktioniert mit "var" in Chrome für mich (Linux / Version 52.0.2743.82 (64-bit))
Zeppelin

> Übrigens ist es ES5, nicht wahr? Richtig, wird den Titel jetzt korrigieren
Zeppelin

1
Das Problem sind varHebezeuge, daher ist im Moment der Benutzung definePropertybereits Schluss. Wenn Sie diese beiden Zeilen jedoch in verschiedenen Skripten platzieren (es ist übrigens zulässig), funktioniert dies, da die Eigenschaft zuerst erstellt und vardann ignoriert wird. Beweis: i.stack.imgur.com/lSwbE.png
Qwertiy

10

C

Programm reinigen

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

Erweitertes Programm

#define for(ever) while(1)

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok.
Karl Napf

3
@KarlNapf Die "for" -Schleife befindet sich nicht in einer anderen unendlichen Konstruktion.
Coredump

3
@KarlNapf Ich dachte, dass diese Antwort ausdrücklich von der Regel zugelassen wurde: • Das Patchen des Codes zur Laufzeit oder zur Kompilierungszeit ist zulässig, solange die Textdarstellung unverändert bleibt.
Omar

Es ist die Formulierung "Muss dieselbe für Schleife ausführen", aber dies widerspricht ja der Textdarstellung.
Karl Napf

7

Java

Sauberes Programm:

public class Main {
    public static void main(String[] args) throws Exception {
        for (Integer i = 0; i < 8; i++);
    }
}

Erweitertes Programm:

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] intcache = (Integer[]) c.get(cache);
        intcache[129] = intcache[128];

        for (Integer i = 0; i < 8; i++);
    }
}

Legt die Ganzzahl im Ganzzahl-Cache fest, die 1 bis 0 enthalten soll, und bewirkt, dass i++nichts unternommen wird (sie setzt iauf die zwischengespeicherte Ganzzahl, die 1 enthalten soll, aber da diese Ganzzahl tatsächlich 0 enthält, ändert sich nichts).


Schlagen Sie mich zu, diese Lösung ist identisch mit meiner eigenen.
Hypino

6
Dies ist nicht wirklich eine idiomatische Java for-Schleife, die wahrscheinlich inteher das Unboxed als das relativ Heavyweight verwenden würde Integer.

7

C ++

int main() 
{
#define int bool
  for (int x=0; x<8; ++x);
  return 0;
}

boolkann nur 0 oder 1 sein. Inspiriert von der Perl-Antwort von primo .


6

Python 3 (3.5.0)

Reinigungsprogramm:

for i in range(8):
    print(i)

Erweitert

import sys

from ctypes import *

code = sys._getframe().f_code.co_code

cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-4] = 113
cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-3] = 160

for i in range(8):
    print(i)

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 113er lesbarer oder besser lesbar ist JUMP_ABSOLUTE. Er ändert den Operanden in 160den Befehl, an dem die for-Schleife beginnt, und erstellt am Ende des Programms eine GOTO-Anweisung.

Das erweiterte Programm druckt die Zahlen 0..7unendlich oft ohne Stapelüberlauf oder ähnliches.


6

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

for(;$i<8;$i++);

Erweitert

$i='a';
for(;$i<8;$i++);

Mit PHP können Sie bestimmte Zeichenfolgen wie folgt inkrementieren:

'a' -> 'b'
'b' -> 'c'
'z' -> 'aa'
'aa' -> 'ab'
'aab' -> 'aac'
etc

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


Das ist im Sinne des Wettbewerbs und sehr interessant. Tatsächlich wurde nichts darüber gesagt, das anfängliche Assignmnet zu unterlassen, also ist das ein Randfall. Tatsächlich wurde erwartet, dass es keinen Erweiterungspunkt zwischen der Zuweisung von 0 und Iterationen gibt. Aber ich werde es jetzt nicht verbieten, da ich einige interessante Randfälle sehe, die darauf basieren, und es nicht leicht ist, sie zu überbeanspruchen.
Qwertiy

2
@Qwertiy "Das ist also ein Randfall." PHP auf den Punkt gebracht :)
ToXik-yogHurt

6

Perl

Code bereinigen

for ($x = 0; $x < 8; $x++) {}

Erweiterter Code

sub TIESCALAR {bless []}
sub FETCH {}
sub STORE {}
tie $x, "";

for ($x = 0; $x < 8; $x++) {}

Die meisten Perl-Variablen sind nur Variablen. Die Sprache verfügt jedoch auch über eine tieFunktion, 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 den forSchleifenzähler mit dem Programm selbst verknüpfen. Das Implementieren von TIESCALARallow 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$xundef


5

WinDbg

Reinigen

.for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { }

Erweitert

aS < |;                                            * Create alias of < as |
.block {                                           * Explicit block so aliases are expanded
    .for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { } * Condition is now @$t0 | 8, always true
}

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, also anything | 8immer wahr.

Hinweis: Das .blockwird nicht benötigt, wenn das aSund .fortatsächlich wie hier gezeigt als zwei verschiedene Zeilen eingegeben werden. Es wird nur benötigt, wenn sich das aSund .forin derselben Zeile befinden.


5

Mathematica

Reinigen

For[x = 0, x < 8, ++x,]

Erweitert

x /: (x = 0) := x = -Infinity;
For[x = 0, x < 8, ++x,]

5

Common Lisp

Code bereinigen

(dotimes(i 8))

Erweitert

(shadowing-import(defmacro :dotimes(&rest args)'(loop)))
(dotimes(i 8))

Es wird ein Makro mit dem Namen keyword:dotimesaka :dotimes(siehe 11.1.2.3 Das KEYWORD-Paket ) definiert, das sich als Endlosschleife erweitert. Das defmacroMakro gibt den Namen des zu definierenden Makros zurück, der weitergeleitet werden kann shadowing-import. Dieses neue dotimesSymbol gibt dem Standard einen Schatten (der in tragbaren Programmen nicht neu definiert oder lexikalisch an ein anderes Makro gebunden werden sollte).

Augmented (2)

(set-macro-character #\8 (lambda (&rest args) '(loop)))
(dotimes(i 8))

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:

(list 6789)

... lautet wie folgt:

(list 67 (loop) 9)

Sie können Tests auf Ideone ausführen: https://ideone.com/sR3AiU .


4

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:

for x in 1..8
  # Some code here
end

Erweitert

Die for-Schleife ruft nur (1..8).eachden angegebenen Codeblock auf, daher ändern wir diese Methode:

class Range
  def each
    i = first
    loop { yield i; i+= 1 }
  end
end

for x in 1..8
  # Some code here
end

4

Haskell

Saubere Version:

import Control.Monad (forM_)

main = forM_ [0..8] $ \i -> print i

Erweiterte Version:

import Control.Monad (forM_)

data T = C

instance Num T where
    fromInteger _ = C

instance Enum T where
    enumFromTo _ _ = repeat C

instance Show T where
    show _ = "0"

default (T)

main = forM_ [0..8] $ \i -> print i

Es ist recht einfach, wirklich: wir unsere eigene Art nur definieren , Tso dass seine enumFromToInstanz eine unendliche Folge ist, dann Typ verwenden säumige so , dass die UN-Typ-kommentierten Werte 0und 8werden als Typ genommen T.


1
Gute Idee, den Standardtyp für Haskells überladene numerische Literale zu ändern.
nimi

3

///

Es gibt keine expliziten forSchleifen in ///, sie können aber simuliert werden (es ist schließlich komplett).

Reinigen:

/1/0/
/2/1/
/3/2/
/4/3/
/5/4/
/6/5/
/7/6/
/8/7/
8

Erweitert:

/0/0/
/1/0/
/2/1/
/3/2/
/4/3/
/5/4/
/6/5/
/7/6/
/8/7/
8

Was ist los?

Während das erste Programm von 8 auf 0 herunterzählt, zählt das zweite /0/0/ Regel ersetzt 0durch 0bis in alle Ewigkeit.


Und ich dachte, dass du /0/1//1/2/.../7/8//8/8/8stattdessen etwas tun würdest, um hoch zu zählen.
Erik der Outgolfer

3

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

for(a of [0,1,2,3,4,5,6,7]);

Das hindert natürlich niemanden daran, sich mit dem Array-Prototypen herumzuschlagen ...

Erweitert

Array.prototype[Symbol.iterator]=function(){return {next: function(){return {done: false}}}}
for(a of [0,1,2,3,4,5,6,7]);

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.


"Schleifenverhalten sollte bei leerer Schleife gleich sein"
Qwertiy 29.11.16

Verdammt, das habe ich verpasst - ich muss etwas herausfinden.
Marcus Dirr

Soweit ich das beurteilen kann, ist es nicht möglich, die Herausforderung mit einer C-style for-Schleife in Javascript zu meistern, es sei denn, Sie brechen eine Regel - entweder indem Sie etwas darin haben (wie meine Lösung) oder indem Sie die Schleife vormassieren Erklärung in Ihrem sauberen Code (wie bei Cedric Reichenbach).
Marcus Dirr

Eigentlich gibt es einige Möglichkeiten. Weg mit globaler Variable ist bereits gebucht, aber es gibt noch einige mehr, die varin der Schleife zulassen.
Qwertiy

Wie gesagt, soweit ich das beurteilen kann. Nachdem ich diesen Kommentar abgegeben hatte, sah ich die globale Variable und trat mich.
Marcus Dirr

2

C ++

Verwendet 2 Erweiterungspunkte:

struct True {
  True(int x){}
  bool operator<(const int&){
    return true;
  }
  void operator++(){}
};


int main() 
{
#define int True
  for (int x=0; x<8; ++x);
  return 0;
}

Das Reinigungsprogramm ist dasselbe wie in der Beschreibung.


Schön, kann aber "optimiert" werden :) Es gibt einige interessante integrierte Funktionen in C ++, um eine andere Antwort zu geben.
Qwertiy

2

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

>> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)

>> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
[                                              a;
++++++++ ++++++++                              a = a plus 16 (mod 256)) {
>.<                                              loop body (print b)
]                                            }

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.

  • a + b * 8 (mod 256) == 0 (für saubere Version)
  • c + a + b * n (mod 256)> 0 für alle n (für die erweiterte Version)
  • a> 0

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

+                                            increment a (only change)
>> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)

>> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
[                                              a;
++++++++ ++++++++                              a = a plus 16 (mod 256)) {
>.<                                              loop body (print b)
]                                            }

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örtlichen 8wie 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.


2

Haskell

Reinigen

import Control.Monad (forM_)

main = forM_ [0..8] $ \i -> print i

Erweitert

import Control.Monad (forM_)

import Prelude hiding (($))
import Control.Monad (when)

f $ x = f (\i -> x i >> when (i == 8) (f $ x))

main = forM_ [0..8] $ \i -> print i

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 iist 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] printund 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 $!


1

C ++

int main() 
{
  int y;
#define int
#define x (y=7)
  for (int x=0; x<8; ++x);
  return 0;
}

Lässt sich xzu 7 auswerten. Funktioniert nicht in C, da es einen Wert bei Zuweisung und Inkrementierung erfordert.


1

Nim

Die idiomatische Version mit countup :

Reinigen

for i in countup(1, 8):
  # counting from 1 to 8, inclusive
  discard

Erweitert

iterator countup(a: int, b: int): int =
  while true:
    yield 8

for i in countup(1, 8):
  # counting 8s forever
  discard

Einfach und sehr ähnlich der Python-Antwort, die neu definiert wirdrange . Wir definieren countupdie 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

for i in 1..8:
  # counting from 1 to 8, inclusive
  discard

Erweitert

iterator `..`(a: int, b: int): int =
  while true:
    yield 8

for i in 1..8:
  # counting 8s forever
  discard

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.


1

GolfScript

Reinigen

0{.8<}{)}while;

Erweitert

{.)}:8;
0{.8<}{)}while;

Es weist der Variablen 8 die Funktion zu, die n + 1 zurückgibt


1

tcl

Normal:

for {set i 0} {$i<8} {incr i} {}

Erweitert:

proc incr x {}
for {set i 0} {$i<8} {incr i} {}

Die Idee ist, den incrBefehl, der zum Inkrementieren der Variablen verwendet wird i, so zu definieren , dass er tatsächlich nicht inkrementiert wird!

Kann getestet werden unter: http://rextester.com/live/QSKZPQ49822


1

x86_64-Assembly

Sauberes Programm:

mov rcx, 8
loop_start:
sub rcx, 1
cmp rcx,0
jne loop_start
mov rax, 0x01
mov rdi, 0
syscall

Die Art von Schleife, die ein Assembly-Programmierer verwenden würde, gefolgt von einem Exit-Systemaufruf, um anschließend keine jmp loop_startAnweisung hinzufügen zu können .

Erweitertes Programm:

global start
section .text
start:
mov rcx, -1
jmp loop_start
mov rcx, 8
loop_start:
sub rcx, 1
cmp rcx,0
jne loop_start
mov rax, 0x01
mov rdi, 0
syscall

Es tut uns auch leid, wenn es schlecht ist, dass das Clean-Programm keinen Entropoint oder keinen hat section .text


Wird es nach einem Ganzzahlüberlauf nicht aufhören?
Qwertiy

1
Oh, äh ... vielleicht. Aber es wird lange dauern? Ich habe irgendwie vergessen, dass das passieren könnte, da ich größtenteils ein Hochsprachenprogrammierer
bin

0

JavaScript

Reinigen:

for (var i = 0; !(i > Math.PI * 2.5); i++);

Erweitert:

window.Math = {PI: NaN};
for (var i = 0; !(i > Math.PI * 2.5); i++);

Scheint keine typische Schleife zu sein ...
Qwertiy

Ja, ich habe den Begriff typisch irgendwie ausgedehnt ...: /
Cedric Reichenbach

0

C ++

Programm reinigen

Eine schöne, normale Schleife, die von 0 bis 7 durchläuft.

#include <iostream>

int main() {

  for (short i = 0; i < 8; i++) {
    // Print `i` with a newline.
    std::cout << i << std::endl;
  }    

}

Erweitertes Programm

Der Präprozessor von C ++ ist eine ziemlich gefährliche Funktion ...

#include <iostream>
#define short bool

int main() {

  for (short i = 0; i < 8; i++) {
    // Print `i` with a newline.
    std::cout << i << std::endl;
  }    

}

Die einzige Zeile, die wir hinzufügen mussten, war #define short bool. Dies macht ieinen Booleschen Wert anstelle einer kurzen Ganzzahl, und der Inkrementoperator ( i++) führt nach iErreichen von 1 nichts aus . Die Ausgabe sieht dann folgendermaßen aus:

0
1
1
1
1
1
...

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.