8 devrait devenir Infinity [fermé]

19

Jetons un coup d'œil à une boucle typique, qui effectue généralement 8 itérations:

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

Vous devez le rendre infini!


C'est un de pour toutes les langues qui prennent en charge une telle forme de forboucle. Ainsi, la solution avec le score le plus élevé (votes positifs moins votes négatifs) gagne.

Si votre langue a l'autre forme de forboucle, mais vous êtes sûr, vous pouvez faire quelque chose de cool avec elle, n'hésitez pas à poster la réponse et à la marquer comme non compétitive. Je me réserve le droit d'élargir la portée des constructions et des langages disponibles, mais il ne sera jamais réduit, alors n'ayez pas peur de laisser tomber des solutions précédemment correctes.


Quelle est la solution?

La solution se compose de deux programmes.

Le premier programme est un programme propre . C'est le programme typique de votre langue avec la forboucle faisant 8 itérations. Ce devrait être le programme normal, n'importe quel développeur pourrait écrire. Pas de hacks spéciaux à des fins de préparation. Par exemple:

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

Le deuxième programme est augmenté. Ce programme doit contenir tout le code du programme propre et du code supplémentaire. Le nombre de points d'extension est limité , voir la section complète des règles pour plus de détails. Un programme augmenté pour le propre ci-dessus peut être

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

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

C'est juste un exemple (non compilable en C ++) pour montrer une idée. Le vrai programme augmenté correct doit être compilable, fonctionner et avoir une boucle infinie.

Règles complètes

Les deux programmes:

  • Toute langue prenant en charge de telles forboucles est correcte.
  • Le corps de la boucle doit être vide. Plus précisément, vous pouvez placer une sortie ou un autre code dans la boucle, mais le comportement de la boucle doit être le même en cas de boucle vide.

Programme propre:

  • La boucle utilise un compteur entier ou numérique et effectue 8 itérations:

    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++
    
  • Les types définis par l'utilisateur ne sont pas autorisés.

  • L'utilisation de la propriété (à l'exception de la variable globale) au lieu de la variable de boucle est interdite.
  • La déclaration de variable peut être à l'intérieur ou à l'extérieur de la boucle. Le code suivant est correct:

    int x;
    for(x=0; x<8; ++x);
    
  • L'incrément de préfixe ou de postfixe peut être utilisé.

  • La limite de boucle 8doit être écrite comme un littéral constant sans être sauvegardée dans une constante ou une variable nommée. Il est fait pour empêcher les solutions basées sur la déclaration d'une variable ou d'une constante égale à 8, puis la réaffectation, la substitution ou l'observation par l'autre valeur:

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

Programme augmenté:

  • Doit contenir tout le code du code propre.
  • Devrait étendre le programme propre dans un nombre limité de points d'extension.
  • Doit exécuter la même for boucle qu'une boucle infinie elle-même.
    Placer la boucle dans une autre construction infinie n'est pas correct.
  • La correction à l'exécution ou à la compilation du code est autorisée tant que sa représentation textuelle est inchangée.
  • Placer la construction dans une chaîne et passer à evaln'est pas autorisé.

Points d'extension:

  • N'importe où en dehors du fragment avec du code propre, y compris d'autres fichiers ou autres assemblys.
  • fordéclaration (en une seule pièce - forconstruction et son corps) doit rester inchangée.
  • La déclaration de variable doit rester la même.
  • N'importe quel endroit entre des instructions simples peut être utilisé comme point d'extension.
  • Si et seulement si la variable a été déclarée en dehors de la boucle et sans affectation immédiate de la valeur, une telle affectation peut être ajoutée.
/* 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: Si possible, veuillez fournir un lien vers l'IDE en ligne.

Qwertiy
la source
2
@Oliver, comme je le sais, "le score le plus élevé (votes positifs moins votes négatifs)" correspond exactement aux valeurs par défaut pour le concours de popularité , au moins il est écrit dans la description du tag: "Un concours de popularité est un concours où la réponse avec le plus grand nombre de votes correspond (votes positifs moins votes négatifs) gagne. " Mais je peux l'ajouter explicitement à la question.
Qwertiy
1
@Maltysen, il y a beaucoup de solutions intéressantes dans les langues avec ces constructions. Il existe C et C ++ (avec des solutions absolument différentes), C #, Java, Javascript, php, Perl, Groovy. Je suis sûr qu'il y en a beaucoup plus. Quoi qu'il en soit, je suis ouvert pour agrandir la question et cela est spécifié dans les règles. Si vous pouvez créer quelque chose d'utile dans une autre langue - postez-le. S'il a une réplication positive, les règles peuvent être élargies.
Qwertiy
4
Faire cela comme un concours de popularité est un peu gênant car il n'y a pas de description des critères que les électeurs devraient choisir lors du vote (ce qui rend la condition de victoire subjective). Je travaillais sur une solution de code-golf sur la base que beaucoup de gens ici trouvent les solutions de golf intéressantes et donc elles pourraient être populaires; cela semble être une condition de victoire réalisable pour le défi.
2
1. " compteur entier ou numérique " est un peu trop vague. Par exemple, cela inclut-il java.lang.Integer? 2. Ce serait mieux avec un critère de victoire approprié.
Peter Taylor
1
1. Oui, c'est le cas. 2. Qu'est-ce que exactement gagner des creteria? PS: Nous pouvons continuer sur la méta .
Qwertiy

Réponses:

33

Python3

Programme propre:

Il s'agit simplement d'un compte à rebours standard en boucle.

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

Programme augmenté:

import ctypes

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

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

Il utilise le cache int pour redéfinir 8ce 9qui rend le n -= 1no-op efficace , car 9-1 = 8qui nrevient à 9nouveau, provoquant la boucle infinie.

Vous pouvez voir le cache int en action en ligne ici (bien évidemment sans la boucle infinie car il est en ligne).

Maltysen
la source
Pourriez-vous fournir un lien vers onlinde IDE, s'il vous plaît? ideone.com/aI3ZrI - semble ne pas fonctionner là-bas.
Qwertiy
@Qwertiy, j'ai essayé de l'exécuter dans repl.it, mais il se bloque, ce qui est normal car ce sera une boucle infinie. Je sais que les choses de cache int fonctionne, parce que ce où je avec la façon d' expériences diverses ensemble 8à9
Maltysen
Fonctionne vraiment là-bas. Étrange qu'ils n'aient pas de limite de temps comme l'ideone (5 sec). Ils montrentPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy
Lien @Qwertiy sans la boucle: repl.it/E4fx/0
Maltysen
C'est intéressant ...
Qwertiy
22

Python 3

Programme propre:

La façon standard de faire quelque chose 8 fois en python est:

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

Programme augmenté:

Cependant, si nous remplaçons la fonction de générateur de plage pour produire infiniment 1, cela devient une boucle infinie ...

def range(x):
    while 1: yield 1

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

Nous pouvons aller plus loin et créer une fonction de générateur qui, au lieu de produire infiniment 1, compte pour toujours:

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

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

Test sur repl.it

FlipTack
la source
2
Cachez ça au milieu d'un énorme module ...
Benjamin
21

Perl

Nettoyer

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

Augmentée

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

Ideone .

primo
la source
16
Oh, c'est vraiment intelligent. Pour tous ceux qui ne connaissent pas Perl: c'est $iun alias pour devenir l'alias d'une variable spéciale qui ne peut contenir que des booléens, donc une fois qu'il atteint 1, il est immunisé contre l'incrémentation.
10

ES5 + (Javascript)

EDIT : Suppression de la déclaration de variable explicite, sinon elle a été hissée et une propriété window.x non configurable a été créée (à moins qu'elle ne soit exécutée ligne par ligne dans la console REPL).

Explication:

Profite du fait que toute variable de portée globale est également une propriété de l' objet window et redéfinit la propriété "window.x" pour avoir une valeur constante de 1.

Nettoyer

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

Augmentée

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

REMARQUE : pour que cela fonctionne dans Node.js, remplacez simplement "window" par "global" (testé dans Node.js 6.8.0)

Zeppelin
la source
1
Au fait, c'est ES5, n'est-ce pas?
Qwertiy
De plus, cela ne fonctionne pas avec varCrome. Mais vous pouvez supprimer vardes deux programmes - ce sera ok.
Qwertiy
@Qwertiy, cela fonctionne avec "var" dans Chrome pour moi (Linux / Version 52.0.2743.82 (64 bits))
zeppelin
> Au fait, c'est ES5, non? Vrai, corrigera le titre maintenant
zeppelin
1
Le problème est les varpalans, donc au moment de l'utiliser definePropertydéjà exitst. Mais si vous placez ces 2 lignes dans des scripts différents (en passant, c'est autorisé), cela fonctionnerait, car la propriété sera créée en premier et varensuite sera ignorée. Preuve: i.stack.imgur.com/lSwbE.png
Qwertiy
10

C

Programme propre

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

Programme augmenté

#define for(ever) while(1)

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}
Omar
la source
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 La boucle "for" n'est pas dans une autre construction infinie.
coredump
3
@KarlNapf Je pensais que cette réponse était explicitement autorisée par la règle: • La correction à l'exécution ou à la compilation du code est autorisée tant que sa représentation textuelle est inchangée.
Omar
C'est le libellé "Doit exécuter la même chose pour la boucle" mais oui, cela entre en conflit avec la représentation textuelle.
Karl Napf
7

Java

Programme propre:

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

Programme augmenté:

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

Définit l'entier dans le cache entier qui doit contenir 1 à 0, ce qui i++fait que rien ne fait (il définit il'entier mis en cache qui devrait contenir 1, mais puisque cet entier contient réellement 0, rien ne change).

insert_name_here
la source
Battez-moi, cette solution est identique à la mienne.
Hypino
6
Ce n'est pas vraiment un Java idiomatique pour la boucle, qui utiliserait probablement le intnon- boxé plutôt que le poids relativement lourd Integer.
7

C ++

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

boolne peut être que 0 ou 1. Inspiré par la réponse Perl de primo .

Karl Napf
la source
6

Python 3 (3.5.0)

Programme propre:

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

Augmentée

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)

Cette solution est différente des autres écrites en Python en ce qu'elle modifie en fait le code source à la volée. Tout le contenu de la boucle for peut être changé en n'importe quel code souhaité.

Le code modifie l'avant-dernier opcode pour être 113ou plus lisible - JUMP_ABSOLUTE. Il change l'opérande en 160- l'instruction où commence la boucle for, créant en fait une instruction GOTO à la fin du programme.

Le programme augmenté imprime les nombres 0..7infiniment de fois sans débordement de pile ou similaire.

Bleu
la source
6

PHP

Je pense que cela suit les règles du point d'extension; Je ne suis pas totalement clair sur le point 4. Il est très similaire à la réponse perl de @ primo donc je pense que cela compte.

Nettoyer

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

Augmentée

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

PHP vous permet d'incrémenter certaines chaînes, comme ceci:

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

Toutes ces chaînes sont évaluées à 0, donc cela bouclera pratiquement pour toujours (sauf en cas de manque de mémoire).

ToXik-yogHurt
la source
C'est dans l'esprit de la compétition et c'est très intéressant. En fait, rien n'a été dit sur la suppression de l'affectation initiale, c'est donc un cas particulier. En fait, il était prévu qu'il n'y ait pas de point d'extension entre l'attribution de 0 et les itérations. Mais je ne vais pas l'interdire maintenant car je vois des cas de bord intéressants basés sur cela et il n'est pas facile d'en abuser.
Qwertiy
2
@Qwertiy "c'est donc un cas de bord." PHP en bref :)
ToXik-yogHurt
6

Perl

Code propre

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

Code augmenté

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

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

La plupart des variables Perl ne sont que des variables. Cependant, le langage a également une tiefonctionnalité, qui vous permet de donner efficacement des getters et setters aux variables. Dans ce programme, je transforme le package principal (dont le nom est la chaîne nulle) en l'équivalent d'une classe à partir d'un langage orienté objet, tout en le faisant être un programme. Cela me permet de lier le forcompteur de boucles au programme lui-même. La mise en œuvre TIESCALARpermet tiede réussir; la valeur de retour de TIESCALARest censée être une référence à tout état interne que nous devons conserver associé à la variable, mais comme nous n'en avons pas besoin, nous renvoyons une référence de tableau vide en tant qu'espace réservé. Nous donnons ensuite les implémentations les plus simples possibles du getter et du setter; aucun d'eux ne fait quoi que ce soit, donc tente d'attribuer à$xn'ont aucun effet, et les tentatives de lecture reviennent toujours undef, ce qui est numériquement inférieur à 8.


la source
5

WinDbg

Nettoyer

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

Augmentée

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
}

Cette approche crée un alias pour <as| , donc quand il <est rencontré dans le code, l'alias est développé |et au niveau du bit ou est effectué au lieu de moins que. Dans WinDbg, toutes les valeurs non nulles sont vraies, anything | 8c'est donc toujours vrai.

Remarque: le .blockn'est pas réellement nécessaire si le aSet .forsont réellement entrés sur deux lignes différentes comme indiqué ici, il n'est requis que lorsque le aSet .forsont sur la même ligne.

Lait
la source
5

Mathematica

Nettoyer

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

Augmentée

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

Lisp commun

Code propre

(dotimes(i 8))

Augmentée

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

Une macro nommée keyword:dotimes, aka :dotimes(voir 11.1.2.3 Le package KEYWORD ) est définie et se développe comme une boucle infinie. La defmacromacro renvoie le nom de la macro en cours de définition, qui peut être alimenté shadowing-import. Ainsi, ce nouveau dotimessymbole masque le standard (qui ne doit pas être redéfini ou lié lexicalement à une autre macro dans les programmes portables).

Augmenté (2)

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

Lorsque nous lisons le caractère 8, nous le remplaçons par (loop). Cela signifie que ce qui précède se lit comme (dotimes (i (loop)))et donc le code ne termine jamais le calcul de la borne supérieure. Cela affecte toutes les occurrences de 8, pas seulement celle de la boucle. En d'autres termes, 8 représente vraiment l'infini. Si vous êtes curieux, lorsque la table de lecture est modifiée comme ci-dessus, le caractère 8 devient "terminaison" et se détache des autres nombres / symboles en cours de lecture:

(list 6789)

... se lit comme suit:

(list 67 (loop) 9)

Vous pouvez exécuter des tests sur Ideone: https://ideone.com/sR3AiU .

coredump
la source
4

Rubis

Nettoyer

Ce type de boucle for n'est pas très utilisé dans Ruby, mais un tutoriel typique vous dira que c'est la façon de procéder:

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

Augmentée

La boucle for appelle juste (1..8).eachavec le bloc de code donné, nous changeons donc cette méthode:

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

for x in 1..8
  # Some code here
end
daniero
la source
4

Haskell

Version propre:

import Control.Monad (forM_)

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

Version augmentée:

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

C'est assez basique, vraiment: nous définissons simplement notre propre type de Tsorte que son enumFromToinstance soit une séquence infinie, puis utilisons la valeur par défaut du type de sorte que les valeurs non annotées 0et 8soient prises comme type T.

Cactus
la source
1
Belle idée de changer le type par défaut pour les littéraux numériques surchargés de Haskell.
nimi
3

///

Il n'y a pas de forboucles explicites dans ///, mais peut être simulé (c'est complet après tout).

Nettoyer:

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

Augmenté:

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

Que se passe-t-il?

Alors que l'ancien programme décompte de 8 à 0, la /0/0/règle de ce dernier sera remplacée 0par 0jusqu'à l'éternité.

Cedric Reichenbach
la source
Et je pensais que vous feriez en fait quelque chose comme /0/1//1/2/.../7/8//8/8/8compter à la place.
Erik the Outgolfer
3

Javascript ES6

OK, voici une version qui fonctionne en utilisant l'ES6 pour ... de la construction de boucle. Je vais même vous donner un tableau clair pour que nous soyons sûrs qu'il n'y a pas de drôle de chose:

Nettoyer

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

Bien sûr, cela n'empêche pas quelqu'un de jouer avec le prototype Array ...

Augmentée

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

Cela fonctionne en écrasant l'itérateur par défaut afin qu'il ne se termine jamais, bloquant ainsi tout dans une boucle infinie. Le code n'a même pas la possibilité d'exécuter les éléments dans la boucle.

Marcus Dirr
la source
"le comportement de la boucle doit être le même en cas de boucle vide"
Qwertiy
Bon sang, j'ai raté ça - je vais devoir trouver quelque chose.
Marcus Dirr
Pour autant que je sache, il n'est pas possible de faire ce que le défi avec une boucle de style C pour Javascript sauf si vous enfreignez une règle - soit en ayant quelque chose à l'intérieur (comme ma solution) ou en pré-massant la boucle déclaration dans votre code propre (comme avec Cedric Reichenbach).
Marcus Dirr
En fait, il existe plusieurs moyens. Le chemin avec la variable globale est déjà affiché, mais il y en a d'autres, permettant vardans la boucle.
Qwertiy
Comme je l'ai dit, pour autant que je sache. J'ai vu la manière variable globale après avoir fait ce commentaire et me suis donné un coup de pied.
Marcus Dirr
2

C ++

Utilise 2 points d'extension:

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

Le programme de nettoyage est le même que dans la description.

Karl Napf
la source
Bien, mais peut être "optimisé" :) Il y a quelques extensions intéressantes en C ++ pour faire une autre réponse.
Qwertiy
2

Brainfuck

J'imprime un «0» à chaque itération, juste pour faciliter le comptage des itérations. Mais n'importe quel code pourrait y être inséré sans changer le fonctionnement de la boucle.

Nettoyer

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

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

Essayez-le en ligne

La version augmentée repose sur l'implémentation Brainfuck commune avec des cellules 8 bits. Sur ces implémentations, "incrément" est en fait "incrément (mod 256)". Ainsi, pour trouver une boucle qui itérera exactement 8 fois dans la version propre et sans cesse dans la version augmentée, nous pouvons simplement trouver une solution au système d'inégalités suivant.

  • a + b * 8 (mod 256) == 0 (pour la version propre)
  • c + a + b * n (mod 256)> 0 pour tous n (pour version augmentée)
  • a> 0

Dans ce cas, nous laissons a = 128, b = 16 et c = 1. Évidemment 128 + 16 * 8 = 256 (et 256 (mod 256) = 0) et 128> 0, et puisque b est pair, c + a + b * n est impair pour tout a + c impair, et ne sera donc jamais un multiple pair de 256 dans de tels cas. Nous choisissons c = 1 pour des raisons de simplicité. Ainsi, le seul changement dont nous avons besoin est un seul +au début du programme.

Augmentée

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

Essayez-le en ligne

Je laisse au PO le soin de déterminer si cette entrée est en compétition. Brainfuck n'a pas de boucle for explicite, mais la forme de boucle que j'ai utilisée est aussi proche que possible. ++++++++est aussi proche d'un littéral 8que possible; J'en ai inclus plusieurs.

La version propre constitue presque certainement un programme typique écrit dans cette langue, car même le plus court Brainfuck Hello World connu dépend d'une relation de récurrence modulaire avec le travail.

Rayon
la source
2

Haskell

Nettoyer

import Control.Monad (forM_)

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

Augmentée

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

Remplace l'opérateur d'application de fonction habituel $par un qui répète la boucle à chaque fois qu'elle se termine. L'exécution de la version propre imprime 0 à 8, puis s'arrête; la version augmentée imprime de 0 à 8 puis de nouveau de 0 à 8, et ainsi de suite.

Je triche un peu, car ce forM_ [0..8] $ \i -> print in'est pas nécessairement la façon la plus "propre" d'écrire cette boucle en Haskell; de nombreux Haskellers réduiraient le corps de la boucle pour obtenir forM_ [0..8] printet il n'y aurait plus $de priorité. Pour ma défense, j'ai copié le code propre de la réponse de Cactus , qui n'avait pas besoin de cette propriété, donc au moins un programmeur Haskell a écrit ce code sans aucune motivation pour ajouter inutilement le $!

Ben
la source
1

C ++

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

Permet d' xévaluer à 7. Ne fonctionne pas en C car il nécessite une valeur l à l'affectation et à l'incrémentation.

Karl Napf
la source
1

Nim

La version idiomatique, utilisant countup:

Nettoyer

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

Augmentée

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

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

Simple et très similaire à la réponse Python qui redéfinitrange . Nous redéfinissons countup, la façon idiomatique Nim d'itérer d'un int (inclus) à un autre, pour donner 8s à l'infini.

La version la plus intéressante, utilisant l'opérateur de plage ..:

Nettoyer

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

Augmentée

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

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

Très similaire à la solution précédente, sauf que nous redéfinissons l'opérateur de plage .., qui normalement donnerait un tableau [1, 2, 3, 4, 5, 6, 7, 8], à l'itérateur d'avant.

Cuivre
la source
1

GolfScript

Nettoyer

0{.8<}{)}while;

Augmentée

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

Il affecte la fonction renvoyant n + 1 à la variable 8

jimmy23013
la source
1

tcl

Ordinaire:

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

Augmenté:

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

L'idée est de redéfinir la incrcommande utilisée pour incrémenter la variablei , pour ne pas réellement incrémenter!

Peut être testé sur: http://rextester.com/live/QSKZPQ49822

sergiol
la source
1

Assemblage x86_64

Programme propre:

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

Type de boucle que tout programmeur Assembly utiliserait, suivi d'un appel système de sortie afin de ne pas permettre l'ajout d'une jmp loop_startinstruction par la suite.

Programme augmenté:

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

Aussi, désolé s'il est mauvais que le programme propre n'ait pas de point d'entrée ou section .text

goose121
la source
Cela ne s'arrêtera-t-il pas après un débordement d'entier?
Qwertiy
1
Oh, euh ... peut-être. Mais cela prendra longtemps? J'ai en quelque sorte oublié que cela pourrait arriver, étant principalement un programmeur de haut niveau
goose121
0

Javascript

Nettoyer:

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

Augmenté:

window.Math = {PI: NaN};
for (var i = 0; !(i > Math.PI * 2.5); i++);
Cedric Reichenbach
la source
Cela ne semble pas être une boucle typique ...
Qwertiy
Ouais, j'ai un peu étiré le terme typique ...: /
Cedric Reichenbach
0

C ++

Programme propre

Une belle boucle normale, itérative des numéros 0 à 7.

#include <iostream>

int main() {

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

}

Programme augmenté

Le préprocesseur de C ++ est une fonctionnalité assez dangereuse ...

#include <iostream>
#define short bool

int main() {

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

}

La seule ligne que nous devions ajouter était #define short bool. Cela fait iun booléen au lieu d'un entier court, et donc l'opérateur d'incrémentation ( i++) ne fait rien après avoir iatteint 1. La sortie ressemble alors à ceci:

0
1
1
1
1
1
...
FlipTack
la source