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 concours de popularité pour toutes les langues qui prennent en charge une telle forme de for
boucle. Ainsi, la solution avec le score le plus élevé (votes positifs moins votes négatifs) gagne.
Si votre langue a l'autre forme de for
boucle, 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 for
boucle 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
for
boucles 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
8
doit ê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 à
eval
n'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.
for
déclaration (en une seule pièce -for
construction 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.
java.lang.Integer
? 2. Ce serait mieux avec un critère de victoire approprié.Réponses:
Python3
Programme propre:
Il s'agit simplement d'un compte à rebours standard en boucle.
Programme augmenté:
Il utilise le cache int pour redéfinir
8
ce9
qui rend len -= 1
no-op efficace , car9-1 = 8
quin
revient à9
nouveau, 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).
la source
8
à9
Python 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Python 3
Programme propre:
La façon standard de faire quelque chose 8 fois en python est:
Programme augmenté:
Cependant, si nous remplaçons la fonction de générateur de plage pour produire infiniment 1, cela devient une boucle infinie ...
Nous pouvons aller plus loin et créer une fonction de générateur qui, au lieu de produire infiniment 1, compte pour toujours:
Test sur repl.it
la source
Perl
Nettoyer
Augmentée
Ideone .
la source
$i
un 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.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
Augmentée
REMARQUE : pour que cela fonctionne dans Node.js, remplacez simplement "window" par "global" (testé dans Node.js 6.8.0)
la source
var
Crome. Mais vous pouvez supprimervar
des deux programmes - ce sera ok.var
palans, donc au moment de l'utiliserdefineProperty
dé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 etvar
ensuite sera ignorée. Preuve: i.stack.imgur.com/lSwbE.pngC
Programme propre
Programme augmenté
la source
Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok.
Java
Programme propre:
Programme augmenté:
Définit l'entier dans le cache entier qui doit contenir 1 à 0, ce qui
i++
fait que rien ne fait (il définiti
l'entier mis en cache qui devrait contenir 1, mais puisque cet entier contient réellement 0, rien ne change).la source
int
non- boxé plutôt que le poids relativement lourdInteger
.C ++
bool
ne peut être que 0 ou 1. Inspiré par la réponse Perl de primo .la source
Python 3 (3.5.0)
Programme propre:
Augmentée
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
113
ou plus lisible -JUMP_ABSOLUTE
. Il change l'opérande en160
- 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..7
infiniment de fois sans débordement de pile ou similaire.la source
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
Augmentée
PHP vous permet d'incrémenter certaines chaînes, comme ceci:
Toutes ces chaînes sont évaluées à 0, donc cela bouclera pratiquement pour toujours (sauf en cas de manque de mémoire).
la source
Perl
Code propre
Code augmenté
La plupart des variables Perl ne sont que des variables. Cependant, le langage a également une
tie
fonctionnalité, 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 lefor
compteur de boucles au programme lui-même. La mise en œuvreTIESCALAR
permettie
de réussir; la valeur de retour deTIESCALAR
est 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 à$x
n'ont aucun effet, et les tentatives de lecture reviennent toujoursundef
, ce qui est numériquement inférieur à 8.la source
WinDbg
Nettoyer
Augmentée
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 | 8
c'est donc toujours vrai.Remarque: le
.block
n'est pas réellement nécessaire si leaS
et.for
sont réellement entrés sur deux lignes différentes comme indiqué ici, il n'est requis que lorsque leaS
et.for
sont sur la même ligne.la source
Mathematica
Nettoyer
Augmentée
la source
Lisp commun
Code propre
Augmentée
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. Ladefmacro
macro renvoie le nom de la macro en cours de définition, qui peut être alimentéshadowing-import
. Ainsi, ce nouveaudotimes
symbole masque le standard (qui ne doit pas être redéfini ou lié lexicalement à une autre macro dans les programmes portables).Augmenté (2)
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:... se lit comme suit:
Vous pouvez exécuter des tests sur Ideone: https://ideone.com/sR3AiU .
la source
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:
Augmentée
La boucle for appelle juste
(1..8).each
avec le bloc de code donné, nous changeons donc cette méthode:la source
Haskell
Version propre:
Version augmentée:
C'est assez basique, vraiment: nous définissons simplement notre propre type de
T
sorte que sonenumFromTo
instance soit une séquence infinie, puis utilisons la valeur par défaut du type de sorte que les valeurs non annotées0
et8
soient prises comme typeT
.la source
///
Il n'y a pas de
for
boucles explicites dans ///, mais peut être simulé (c'est complet après tout).Nettoyer:
Augmenté:
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ée0
par0
jusqu'à l'éternité.la source
/0/1//1/2/.../7/8//8/8/8
compter à la place.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
Bien sûr, cela n'empêche pas quelqu'un de jouer avec le prototype Array ...
Augmentée
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.
la source
var
dans la boucle.C ++
Utilise 2 points d'extension:
Le programme de nettoyage est le même que dans la description.
la source
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
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.
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
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éral8
que 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.
la source
Haskell
Nettoyer
Augmentée
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 i
n'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 obtenirforM_ [0..8] print
et 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$
!la source
C ++
Permet d'
x
évaluer à 7. Ne fonctionne pas en C car il nécessite une valeur l à l'affectation et à l'incrémentation.la source
Nim
La version idiomatique, utilisant
countup
:Nettoyer
Augmentée
Simple et très similaire à la réponse Python qui redéfinit
range
. Nous redéfinissonscountup
, 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
Augmentée
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.la source
GolfScript
Nettoyer
Augmentée
Il affecte la fonction renvoyant n + 1 à la variable 8
la source
tcl
Ordinaire:
Augmenté:
L'idée est de redéfinir la
incr
commande utilisée pour incrémenter la variablei
, pour ne pas réellement incrémenter!Peut être testé sur: http://rextester.com/live/QSKZPQ49822
la source
Assemblage x86_64
Programme propre:
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_start
instruction par la suite.Programme augmenté:
Aussi, désolé s'il est mauvais que le programme propre n'ait pas de point d'entrée ou
section .text
la source
Javascript
Nettoyer:
Augmenté:
la source
C ++
Programme propre
Une belle boucle normale, itérative des numéros 0 à 7.
Programme augmenté
Le préprocesseur de C ++ est une fonctionnalité assez dangereuse ...
La seule ligne que nous devions ajouter était
#define short bool
. Cela faiti
un booléen au lieu d'un entier court, et donc l'opérateur d'incrémentation (i++
) ne fait rien après avoiri
atteint 1. La sortie ressemble alors à ceci:la source