8 dovrebbe diventare Infinity [chiuso]


19

Diamo un'occhiata a un ciclo tipico, che di solito esegue 8 iterazioni:

for (int x=0; x<8; ++x);

Devi renderlo infinito!


È un per tutte le lingue che supportano tale forma di forloop. Quindi vince la soluzione con il punteggio più alto (voti meno voti bassi).

Se la tua lingua ha l'altra forma di forloop, ma sei sicuro, puoi creare qualcosa di interessante con esso, sentiti libero di pubblicare la risposta e contrassegnarla come non competitiva. Mi riservo il diritto di ampliare l'ambito delle costruzioni e dei linguaggi disponibili, ma non sarà mai ridotto, quindi non abbiate paura di abbandonare soluzioni precedentemente corrette.


Qual è la soluzione?

La soluzione è composta da due programmi.

Il primo programma è un programma pulito . È il tipico programma nella tua lingua con il forciclo che fa 8 iterazioni. Dovrebbe essere il normale programma, qualsiasi sviluppatore potrebbe scrivere. Nessun hack speciale per scopi di preparazione. Per esempio:

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

Il secondo programma è aumentato. Questo programma dovrebbe contenere tutto il codice del programma pulito e alcuni codici aggiuntivi. Esistono un numero limitato di punti di estensione, vedere la sezione completa delle regole per i dettagli. Può essere un programma aumentato per quello pulito sopra

inline bool operator < (const int &a, const int &b)
{
  return true;
}

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

Questo è solo un esempio (non compilabile in C ++) per mostrare un'idea. Il vero programma aumentato corretto deve essere compilabile, funzionante e con loop infinito.

Regole complete

Entrambi i programmi:

  • Qualsiasi lingua con supporto di tali forloop è ok.
  • Il corpo del loop deve essere vuoto. Più precisamente, è possibile inserire un output o altro codice nel loop, ma il comportamento del loop dovrebbe essere lo stesso in caso di loop vuoto.

Programma pulito:

  • Il ciclo utilizza un contatore intero o numerico ed esegue 8 iterazioni:

    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++
    
  • I tipi definiti dall'utente non sono consentiti.

  • L'uso della proprietà (ad eccezione della variabile globale) invece della variabile loop non è consentito.
  • La dichiarazione della variabile può essere all'interno o all'esterno del ciclo. Il seguente codice è ok:

    int x;
    for(x=0; x<8; ++x);
    
  • È possibile utilizzare l'incremento del prefisso o del postfisso.

  • Il limite di loop 8deve essere scritto come costante letterale senza salvare nella costante o variabile denominata. È fatto per prevenire soluzioni basate sulla dichiarazione di variabile o costante uguale a 8, e quindi riassegnandola, sovrascrivendola o oscurandola con l'altro valore:

    const double n = 8;
    
    int main()
    {
      const double n = 9007199254740992;
      for (double x=0; x<n; ++x);
      return 0;
    }
    

Programma aumentato:

  • Deve contenere tutto il codice da quello pulito.
  • Dovrebbe estendere il programma pulito in un numero limitato di punti di estensione.
  • Deve eseguire lo stesso for loop di un loop infinito stesso.
    Il posizionamento del loop in un'altra costruzione infinita non è corretto.
  • Il runtime o il patching in fase di compilazione del codice sono consentiti purché la rappresentazione testuale di esso sia invariata.
  • Non evalè consentito posizionare la costruzione in una stringa e passare a .

Punti di estensione:

  • Ovunque al di fuori del frammento con codice pulito, inclusi altri file o altri assembly.
  • fordichiarazione (come pezzo unico - forcostruzione e il suo corpo) deve essere mantenuto invariato.
  • La dichiarazione delle variabili deve essere mantenuta invariata.
  • Qualsiasi punto tra semplici istruzioni può essere utilizzato come punto di estensione.
  • Se e solo se la variabile è stata dichiarata al di fuori del ciclo e senza assegnazione immediata del valore, è possibile aggiungere tale assegnazione.
/* 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: se possibile, si prega di fornire un collegamento all'IDE online.


2
@Oliver, come so, "il punteggio più alto (voti meno voti bassi)" è esattamente il valore predefinito per il concorso di popolarità , almeno è scritto nella descrizione del tag: "Un concorso di popolarità è un concorso in cui la risposta con il punteggio più alto corrisponde (voti positivi meno voti negativi) vince ". Ma posso aggiungerlo esplicitamente alla domanda.
Qwertiy,

1
@Maltysen, ci sono molte soluzioni interessanti in lingue con queste costruzioni. Esistono C e C ++ (con soluzioni assolutamente diverse), C #, Java, Javascript, php, Perl, Groovy. Sono sicuro che ce ne sono molti di più. Ad ogni modo, sono aperto all'ampliamento della domanda e questo è specificato nelle regole. Se riesci a creare qualcosa di simile in un'altra lingua, pubblicalo. Se avrà una reazione positiva, le regole possono essere ampliate.
Qwertiy,

4
Fare questo come un concorso di popolarità è un po 'imbarazzante perché non c'è una descrizione di quali criteri gli elettori dovrebbero scegliere quando votano (rendendo soggettiva la condizione di vittoria). Stavo lavorando a una soluzione di golf di codice sulla base del fatto che molte persone qui trovano interessanti le soluzioni di golf e quindi potrebbe essere popolare; sembra che potrebbe essere una condizione di vittoria praticabile per la sfida.

2
1. " contatore intero o numerico " è un po 'troppo vago. Ad esempio include java.lang.Integer? 2. Questo sarebbe meglio con un criterio vincente adeguato.
Peter Taylor,

1
1. Sì, lo fa. 2. Che cosa è esattamente la creteria vincente? PS: possiamo continuare su meta .
Qwertiy,

Risposte:


33

python3

Programma pulito:

Questo è solo un conto alla rovescia standard mentre il ciclo.

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

Programma aumentato:

import ctypes

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

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

Utilizza la cache int per ridefinire il modo 8in 9cui rende effettivamente n -= 1un no-op, dal momento 9-1 = 8che si limita a ntornare di 9nuovo, causando il ciclo infinito.

Puoi vedere la cache int in azione online qui (anche se ovviamente senza il ciclo infinito perché è online).


Potresti fornire un link a onlinde IDE, per favore? ideone.com/aI3ZrI - sembra non funzionare lì.
Qwertiy,

@Qwertiy, ho provato a eseguirlo in repl.it, ma si blocca, il che è prevedibile dal momento che sarà un ciclo infinito. So che la roba int di cache lavora lì, perché è lì che ho sperimentato come impostare 8a9
Maltysen

Funziona davvero lì. Strano che non abbiano limiti di tempo come ideone (5 sec). MostranoPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy il

Link @Qwertiy senza loop: repl.it/E4fx/0
Maltysen

È interessante ...
Qwertiy,

22

Python 3

Programma pulito:

Il modo standard di fare qualcosa 8 volte in Python è:

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

Programma aumentato:

Tuttavia, se sovrascriviamo la funzione del generatore di range per produrre infinitamente 1, diventa un loop infinito ...

def range(x):
    while 1: yield 1

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

Possiamo andare oltre e creare una funzione di generatore che, anziché cedere all'infinito 1, conta per sempre:

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

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

Test su repl.it


2
Nascondilo nel mezzo di un enorme modulo ...
Benjamin,

21

Perl

Pulito

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

Augmented

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

Ideone .


16
Oh, è davvero intelligente. Per chiunque non conosca il Perl: questo è $iun alias per diventare un alias per una variabile speciale che è in grado di contenere solo valori booleani, quindi una volta che raggiunge 1 diventa immune da incrementare.

10

ES5 + (Javascript)

EDIT : rimossa la dichiarazione di variabile esplicita, poiché altrimenti è stata sollevata ed è stata creata una proprietà window.x non configurabile (a meno che non venga eseguita riga per riga nella console REPL).

Spiegazione:

Sfrutta il fatto che qualsiasi variabile con ambito globale è anche una proprietà dell'oggetto window e ridefinisce la proprietà "window.x" per avere un valore costante di 1.

Pulito

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

Augmented

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

NOTA : per farlo funzionare in Node.js, basta sostituire "finestra" con "globale" (testato in Node.js 6.8.0)


1
A proposito, è ES5, no?
Qwertiy,

Inoltre non funziona con varCrome. Ma puoi rimuovere varda entrambi i programmi - andrà bene.
Qwertiy,

@Qwertiy funziona con "var" in Chrome per me (Linux / Versione 52.0.2743.82 (64-bit))
zeppelin

> A proposito, è ES5, no? È vero, correggerò il titolo ora
zeppelin il

1
Il problema sono i varparanchi, quindi al momento del suo utilizzo definePropertysono già usciti. Ma se si inseriscono queste 2 righe in diversi script (a proposito, è consentito), funzionerebbe, poiché la proprietà verrà creata per prima e varquindi verrà ignorata. Prova: i.stack.imgur.com/lSwbE.png
Qwertiy

10

C

Programma pulito

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

Programma aumentato

#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 Il ciclo "for" non si trova all'interno di un'altra costruzione infinita.
coredump,

3
@KarlNapf Pensavo che questa risposta fosse esplicitamente consentita dalla regola: • Il runtime o il patching in fase di compilazione del codice è consentito purché la rappresentazione testuale di esso sia invariata.
Omar,

È la dicitura "Deve eseguire lo stesso per loop" ma sì, questo è in conflitto con la rappresentazione testuale.
Karl Napf,

7

Giava

Programma pulito:

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

Programma aumentato:

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++);
    }
}

Imposta l'Integer nella cache Integer che dovrebbe contenere da 1 a 0, facendo effettivamente i++nulla (imposta isull'Integer memorizzato nella cache che dovrebbe contenere 1, ma dal momento che l'Integer contiene effettivamente 0, nulla cambia).


Battimi, questa soluzione è identica alla mia.
Hypino,

6
Questo non è davvero un idiomatico Java per loop, che probabilmente userebbe il non boxed intpiuttosto che il relativamente pesante Integer.

7

C ++

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

boolpuò essere solo 0 o 1. Ispirato dalla risposta Perl di primo .


6

Python 3 (3.5.0)

Programma pulito:

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

Augmented

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)

Questa soluzione è diversa dalle altre scritte in Python in quanto modifica il codice sorgente al volo. Tutte le cose nel ciclo for possono essere cambiate in qualunque codice sia desiderato.

Il codice cambia il secondo all'ultimo opcode in modo che 113sia più leggibile - JUMP_ABSOLUTE. Cambia l'operando in 160- l'istruzione in cui inizia il ciclo for, in effetti creando un'istruzione GOTO alla fine del programma.

Il programma aumentato stampa i numeri 0..7infinitamente più volte senza traboccare dello stack o simili.


6

PHP

Penso che questo stia seguendo le regole del punto di estensione; Non sono del tutto chiaro al punto 4. È molto simile alla risposta perl di @ primo quindi penso che conti.

Pulito

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

Augmented

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

PHP ti consente di incrementare determinate stringhe, in questo modo:

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

Tutte queste stringhe vengono valutate su 0, quindi questo si ripeterà praticamente per sempre (escludendo in qualche modo la memoria insufficiente).


Questo è nello spirito della competizione e molto interessante. In realtà non è stato detto nulla sull'opportunità di assegnaremnet iniziale, quindi questo è un caso limite. In realtà ci si aspettava che non ci fossero punti di estensione tra l'assegnazione di 0 e le iterazioni. Ma ora non lo consentirò poiché vedo alcuni modi interessanti di basarsi su quello e non è facile da usare eccessivamente.
Qwertiy,

2
@Qwertiy "quindi questo è un caso limite." PHP in breve :)
ToXik-yogHurt

6

Perl

Codice pulito

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

Codice aumentato

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

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

La maggior parte delle variabili Perl sono solo variabili. Tuttavia, la lingua ha anche una tiefunzione, che consente di fornire in modo efficace variabili getter e setter. In questo programma, creo il pacchetto principale (il cui nome è la stringa null) nell'equivalente di una classe da un linguaggio orientato agli oggetti, pur avendo anche un programma. Ciò mi consente di legare il forcontatore di loop al programma stesso. L'implementazione TIESCALARconsente di non avere alcun effetto e i tentativi di leggerlo ritornano sempre , che è numericamente inferiore a 8.tie di avere successo; il valore restituito di TIESCALARè pensato per essere un riferimento a qualsiasi stato interno che dobbiamo mantenere associato alla variabile, ma poiché non ne abbiamo bisogno, restituiamo un riferimento di matrice vuoto come segnaposto. Diamo quindi le implementazioni più semplici possibili di getter e setter; nessuno dei due fa nulla, quindi tenta di assegnare a$xundef


5

WinDbg

Pulito

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

Augmented

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
}

Questo approccio crea un alias per <as |, quindi quando <viene rilevato nel codice l'alias viene espanso |e bit per bit o viene eseguito invece di minore di. In WinDbg tutti i valori diversi da zero sono veritieri, quindi anything | 8è sempre vero.

Nota: The .blocknon è effettivamente necessario se aSe .forsono effettivamente inseriti come due diverse righe come mostrato qui, è richiesto solo quando aSe .forsono sulla stessa riga.


5

matematica

Pulito

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

Augmented

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

5

Lisp comune

Codice pulito

(dotimes(i 8))

Augmented

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

Viene definita una macro denominata keyword:dotimesaka :dotimes(vedere 11.1.2.3 Il pacchetto KEYWORD ) che si espande come un ciclo infinito. La defmacromacro restituisce il nome della macro in corso di definizione, a cui può essere inviato shadowing-import. Pertanto, questi nuovi dotimessimboli ombreggiano quello standard (che non deve essere ridefinito o legato lessicamente a un'altra macro nei programmi portatili).

Aumentato (2)

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

Quando leggiamo il carattere 8, lo sostituiamo con (loop). Ciò significa che quanto sopra si legge come (dotimes (i (loop)))e quindi il codice non termina mai calcolando il limite superiore. Ciò influisce su tutte le occorrenze di 8, non solo su quella nel loop. In altre parole, 8 rappresenta davvero l'infinito. Se sei curioso, quando il readtable viene modificato come sopra, allora il carattere 8 diventa "terminante" e si stacca da altri numeri / simboli attualmente letti:

(list 6789)

... legge come:

(list 67 (loop) 9)

Puoi eseguire i test su Ideone: https://ideone.com/sR3AiU .


4

Rubino

Pulito

Questo tipo di ciclo for non è molto usato in Ruby, ma un tipico tutorial ti dirà che questo è il modo di procedere:

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

Augmented

Il ciclo for chiama solo (1..8).eachcon il blocco di codice dato, quindi cambiamo quel metodo:

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

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

4

Haskell

Versione pulita:

import Control.Monad (forM_)

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

Versione aumentata:

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

È piuttosto semplice, davvero: definiamo semplicemente il nostro tipo in modo Ttale che la sua enumFromToistanza sia una sequenza infinita, quindi usiamo il default di tipo in modo che i valori non annotati 0e 8vengano presi come tipo T.


1
Bella idea di cambiare il tipo predefinito per i letterali numerici sovraccarichi di Haskell.
nimi,

3

///

Non ci sono forloop espliciti in ///, ma possono essere simulati (dopotutto è il turing completo).

Pulito:

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

Augmented:

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

Cosa sta succedendo?

Mentre il primo programma di conto alla rovescia 8-0, il secondo di una /0/0/regola sostituirà 0dal 0fino all'eternità.


E ho pensato che avresti effettivamente fatto qualcosa come /0/1//1/2/.../7/8//8/8/8contare, invece.
Erik the Outgolfer,

3

Javascript ES6

OK, ecco una versione che funziona usando ES6 per ... del costrutto loop. Ti darò anche un array pulito in modo che siamo sicuri che non ci siano affari divertenti:

Pulito

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

Ovviamente, ciò non impedisce a qualcuno di scherzare con il prototipo di array ...

Augmented

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

Questo funziona sovrascrivendo l'iteratore predefinito in modo che non termini mai, bloccando quindi tutto in un ciclo infinito. Il codice non ha nemmeno la possibilità di eseguire le cose all'interno del ciclo.


"Il comportamento del loop dovrebbe essere lo stesso in caso di loop vuoto"
Qwertiy,

Accidenti, mi è mancato - Dovrò capire qualcosa.
Marcus Dirr,

Per quanto posso dire, non è possibile fare ciò che la sfida con uno stile C per loop in Javascript a meno che tu non infranga una regola - o avendo qualcosa al suo interno (come la mia soluzione) o pre-massaggiando il loop dichiarazione nel tuo codice pulito (come con Cedric Reichenbach's).
Marcus Dirr,

In realtà ci sono alcuni modi. Il modo con la variabile globale è già pubblicato, ma ce ne sono alcuni altri, permettendo varnel ciclo.
Qwertiy,

Come ho detto, per quanto ne so. Ho visto la variabile globale dopo aver fatto quel commento e mi sono preso a calci.
Marcus Dirr,

2

C ++

Utilizza 2 punti di estensione:

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;
}

Il programma pulito è lo stesso della descrizione.


Bello, ma può essere "ottimizzato" :) Ci sono alcuni builtin interessanti in C ++ per dare un'altra risposta.
Qwertiy,

2

Brainfuck

Stampo uno '0' ogni iterazione, solo per semplificare il conteggio delle iterazioni. Ma qualsiasi codice può essere inserito lì senza cambiare il funzionamento del ciclo.

Pulito

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

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

Provalo online

La versione aumentata si basa sull'implementazione comune di Brainfuck con celle a 8 bit. Su queste implementazioni, "incremento" è in realtà "incremento (mod 256)". Quindi, per trovare un ciclo che ripeterà esattamente 8 volte nella versione pulita e all'infinito nella versione aumentata, possiamo semplicemente trovare una soluzione al seguente sistema di disuguaglianze.

  • a + b * 8 (mod 256) == 0 (per versione pulita)
  • c + a + b * n (mod 256)> 0 per tutto n (per versione aumentata)
  • a> 0

In questo caso, lasciamo a = 128, b = 16 e c = 1. Ovviamente 128 + 16 * 8 = 256 (e 256 (mod 256) = 0) e 128> 0, e poiché b è pari, c + a + b * n è dispari per qualsiasi dispari a + c, e quindi non sarà mai un multiplo pari di 256 in tali casi. Selezioniamo c = 1 per semplicità. Quindi l'unico cambiamento di cui abbiamo bisogno è un singolo +all'inizio del programma.

Augmented

+                                            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)
]                                            }

Provalo online

Lascio all'OP per determinare se questa voce è in competizione. Brainfuck non ha un esplicito per loop, ma la forma di loop che ho usato è il più vicino possibile. ++++++++è anche il più vicino possibile a un letterale 8; Ne ho inclusi alcuni.

La versione pulita costituisce quasi certamente un tipico programma scritto in questa lingua, poiché anche il Brainfuck Hello World più breve conosciuto dipende da una relazione di ricorrenza modulare con il lavoro.


2

Haskell

Pulito

import Control.Monad (forM_)

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

Augmented

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

Sostituisce il solito operatore dell'applicazione con funzioni $ con uno che ripete nuovamente il ciclo ogni volta che termina. L'esecuzione della versione pulita stampa da 0 a 8 e quindi si interrompe; la versione aumentata stampa da 0 a 8, quindi di nuovo da 0 a 8 e così via.

Imbroglio un po ', forM_ [0..8] $ \i -> print inon è necessariamente il modo "più pulito" per scrivere quel ciclo in Haskell; molti Haskeller ridurrebbero il corpo del loop per ottenere forM_ [0..8] printe quindi non c'è nessun $override. A mia difesa, ho copiato il codice pulito dalla risposta di Cactus , che non aveva bisogno di quella proprietà, quindi almeno un programmatore Haskell ha effettivamente scritto quel codice senza motivazione per aggiungere inutilmente il $!


1

C ++

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

Consente di xvalutare su 7. Non funziona in C perché richiede un valore al momento dell'assegnazione e dell'incremento.


1

Nim

La versione idiomatica, usando countup:

Pulito

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

Augmented

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

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

Semplice e molto simile alla risposta Python che ridefiniscerange . Ridefiniamo countup, il modo Nim idiomatico di iterare da un int (compreso) a un altro, per dare 8s all'infinito.

La versione più interessante, utilizzando l'operatore di gamma ..:

Pulito

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

Augmented

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

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

Molto simile alla soluzione precedente, tranne per il fatto che abbiamo ridefinito l'operatore di intervallo .., che normalmente darebbe un array [1, 2, 3, 4, 5, 6, 7, 8], all'iteratore da prima.


1

GolfScript

Pulito

0{.8<}{)}while;

Augmented

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

Assegna la funzione restituendo n + 1 alla variabile 8


1

TCL

Normale:

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

Augmented:

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

L'idea è di ridefinire il incrcomando utilizzato per incrementare la variabilei , in realtà non incrementare!

Può essere testato su: http://rextester.com/live/QSKZPQ49822


1

x86_64 Assembly

Programma pulito:

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

Il tipo di loop utilizzato da qualsiasi programmatore di Assembly, seguito da un syscall di uscita per non consentire l'aggiunta di jmp loop_startun'istruzione in seguito.

Programma aumentato:

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

Inoltre, scusami se è un male che il programma clean non abbia un punto di accesso o un section .text


Non si fermerà dopo l'overflow dei numeri interi?
Qwertiy,

1
Oh ... forse. Ma ci vorrà molto tempo? Ho dimenticato che ciò potrebbe accadere, essendo per lo più un programmatore di alto livello linguistico
goose121

0

JavaScript

Pulito:

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

Augmented:

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

Non sembra essere un tipico ciclo ...
Qwertiy,

Sì, ho allungato il termine tipico ...: /
Cedric Reichenbach il

0

C ++

Programma pulito

Un bel ciclo normale, che scorre dai numeri da 0 a 7.

#include <iostream>

int main() {

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

}

Programma aumentato

Il preprocessore di C ++ è una caratteristica piuttosto pericolosa ...

#include <iostream>
#define short bool

int main() {

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

}

L'unica linea che dovevamo aggiungere era #define short bool. Questo rende iun valore booleano invece di un numero intero breve, quindi l'operatore di incremento ( i++) non fa nulla dopo iraggiunge 1. L'output ha quindi il seguente aspetto:

0
1
1
1
1
1
...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.