Echemos un vistazo a un bucle típico, que generalmente realiza 8 iteraciones:
for (int x=0; x<8; ++x);
¡Tienes que hacerlo infinito!
Es un concurso de popularidad para todos los idiomas que admiten esa forma de for
bucle. Entonces, la solución con la puntuación más alta (votos positivos menos votos negativos) gana.
Si su idioma tiene la otra forma de for
bucle, pero está seguro, puede hacer algo genial con él, no dude en publicar la respuesta y marcarla como no competitiva. Me reservo el derecho de ampliar el alcance de las construcciones e idiomas disponibles, pero nunca se reducirá, así que no tenga miedo de descartar soluciones previamente correctas.
¿Qué es la solución?
La solución consta de dos programas.
El primer programa es un programa limpio . Es el programa típico en su idioma con el for
ciclo que hace 8 iteraciones. Debería ser el programa normal, cualquier desarrollador podría escribir. No hay hacks especiales para fines de preparación. Por ejemplo:
int main()
{
for (int x=0; x<8; ++x);
return 0;
}
El segundo programa se aumenta. Este programa debe contener todo el código del programa limpio y algún código adicional. Hay un número limitado de puntos de extensión, vea la sección de reglas completas para más detalles. Un programa aumentado para el limpio de arriba puede ser
inline bool operator < (const int &a, const int &b)
{
return true;
}
int main()
{
for (int x=0; x<8; ++x);
return 0;
}
Eso es solo un ejemplo (no compatible en C ++) para mostrar una idea. El programa real correcto aumentado tiene que ser compilable, funcionar y tener bucle infinito.
Reglas completas
Ambos programas:
- Cualquier lenguaje con soporte de tales
for
bucles está bien. - El cuerpo del bucle debe estar vacío. Más precisamente, puede colocar alguna salida u otro código en el bucle, pero el comportamiento del bucle debe ser el mismo en caso de bucle vacío.
Programa limpio:
Loop usa un entero o un contador numérico y realiza 8 iteraciones:
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++
Los tipos definidos por el usuario no están permitidos.
- El uso de la propiedad (excepto la variable global) en lugar de la variable de bucle no está permitido.
La declaración de variable puede estar dentro o fuera del bucle. El siguiente código está bien:
int x; for(x=0; x<8; ++x);
Se puede usar el incremento de prefijo o postfix.
El límite de bucle
8
debe escribirse como un literal constante sin guardarlo en una constante o variable nombrada. Está hecho para evitar soluciones basadas en declarar variable o constante igual a 8, y luego reasignarlo, anularlo o sombrearlo por el otro valor:const double n = 8; int main() { const double n = 9007199254740992; for (double x=0; x<n; ++x); return 0; }
Programa aumentado:
- Debe contener todo el código del limpio.
- Debe extender el programa limpio en un número limitado de puntos de extensión.
- Debe ejecutar el mismo
for
bucle que un bucle infinito.
Colocar el bucle en otra construcción infinita no está bien. - El parche en tiempo de ejecución o en tiempo de compilación del código está permitido siempre que la representación textual del mismo no se modifique.
- Colocar la construcción en una cuerda y pasar a
eval
no está permitido.
Puntos de extensión:
- En cualquier lugar fuera del fragmento con código limpio, incluidos otros archivos u otros ensamblados.
for
declaración (como pieza única -for
construcción y su cuerpo) debe mantenerse sin cambios.- La declaración variable debe mantenerse igual.
- Cualquier lugar entre declaraciones simples puede usarse como punto de extensión.
- Si y solo si la variable se declaró fuera del ciclo y sin una asignación inmediata del valor, dicha asignación se puede agregar.
/* 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;
}
PD: Si es posible, proporcione un enlace a IDE en línea.
java.lang.Integer
? 2. Esto sería mejor con un criterio ganador adecuado.Respuestas:
Python3
Programa limpio:
Esto es solo una cuenta regresiva estándar mientras que el ciclo.
Programa Aumentado:
Utiliza el caché int para redefinir
8
, lo9
que efectivamente hace que eln -= 1
no-op, ya9-1 = 8
que solon
vuelve a funcionar9
, causando el bucle infinito.Puede ver el caché int en acción en línea aquí (aunque obviamente sin el ciclo infinito porque está en línea).
fuente
8
a9
Python 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Python 3
Programa limpio:
La forma estándar de hacer algo 8 veces en python es:
Programa Aumentado:
Sin embargo, si anulamos la función del generador de rango para producir infinitamente 1, se convierte en un bucle infinito ...
Podemos llevar esto más lejos y crear una función generadora que, en lugar de producir infinitamente 1, cuente para siempre:
Prueba en repl.it
fuente
Perl
Limpiar
Aumentado
Ideone .
fuente
$i
un alias para convertirse en un alias para una variable especial que solo es capaz de contener booleanos, por lo que una vez que llega a 1 se vuelve inmune al incremento.ES5 + (Javascript)
EDITAR : Se eliminó la declaración de variable explícita, ya que de lo contrario se levantó y se creó una propiedad window.x no configurable (a menos que se ejecute línea por línea en la consola REPL).
Explicación:
Aprovecha el hecho de que cualquier variable de ámbito global también es una propiedad del objeto de ventana y redefine la propiedad "window.x" para tener un valor constante de 1.
Limpiar
Aumentado
NOTA : Para que esto funcione en Node.js, simplemente reemplace "ventana" con "global" (probado en Node.js 6.8.0)
fuente
var
en Crome. Pero puede eliminarvar
de ambos programas, estará bien.var
polipastos, por lo que al momento de usarlodefineProperty
ya sale. Pero si coloca estas 2 líneas en diferentes scripts (por cierto, está permitido), funcionaría, ya que la propiedad se creará primero yvar
luego se ignorará. Prueba: i.stack.imgur.com/lSwbE.pngC
Programa limpio
Programa aumentado
fuente
Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok.
Java
Programa limpio:
Programa aumentado:
Establece el entero en la memoria caché de enteros que debe contener 1 a 0, haciendo efectivamente
i++
no hace nada (se establecei
en el número entero en caché que debe contener 1, pero dado que ese número entero realmente contiene 0, nada cambia).fuente
int
lugar del relativamente pesadoInteger
.C ++
bool
solo puede ser 0 o 1. Inspirado por la respuesta Perl de primo .fuente
Python 3 (3.5.0)
Programa limpio:
Aumentado
Esta solución es diferente a las otras escritas en Python en que realmente cambia el código fuente sobre la marcha. Todas las cosas en el bucle for se pueden cambiar a cualquier código que se desee.
El código cambia el penúltimo opcode para que sea
113
o más legible -JUMP_ABSOLUTE
. Cambia el operando a160
: la instrucción donde comienza el ciclo for, creando una declaración GOTO al final del programa.El programa aumentado imprime los números
0..7
infinitamente muchas veces sin desbordamiento de pila o similar.fuente
PHP
Creo que esto sigue las reglas del punto de extensión; No estoy del todo claro en el punto 4. Es muy similar a la respuesta perl de @primo, así que creo que cuenta.
Limpiar
Aumentado
PHP te permite incrementar ciertas cadenas, así:
Todas estas cadenas se evalúan a 0, por lo que esto se repetirá prácticamente para siempre (salvo que de alguna manera se quede sin memoria).
fuente
Perl
Código limpio
Código aumentado
La mayoría de las variables de Perl son solo variables. Sin embargo, el lenguaje también tiene una
tie
característica que le permite dar variables de forma eficaz a los captadores y definidores. En este programa, convierto el paquete principal (cuyo nombre es la cadena nula) en el equivalente de una clase de un lenguaje orientado a objetos, a la vez que hago que sea un programa. Eso me permite vincular elfor
contador de bucle al programa en sí. La implementación noTIESCALAR
permite ningún efecto, y los intentos de leerlo siempre regresan , que es numéricamente menor que 8.tie
tener éxito; El valor de retorno deTIESCALAR
debe ser una referencia a cualquier estado interno que necesitemos mantener asociado con la variable, pero debido a que no necesitamos ninguno, devolvemos una referencia de matriz vacía como marcador de posición. Luego damos las implementaciones más simples posibles de getter y setter; ninguno de ellos hace nada, así que intenta asignar a$x
undef
fuente
WinDbg
Limpiar
Aumentado
Este enfoque crea un alias para
<
as|
, por lo que cuando<
se encuentra en el código, el alias se expande|
y se hace a nivel de bits, o se hace en lugar de menos que. En WinDbg, todos los valores distintos de cero son verdaderos, poranything | 8
lo que siempre es cierto.Nota: El
.block
no es realmente necesario si elaS
y.for
se ingresan como dos líneas diferentes como se muestra aquí, solo se requiere cuandoaS
y.for
están en la misma línea.fuente
Mathematica
Limpiar
Aumentado
fuente
Lisp común
Código limpio
Aumentado
Se define una macro llamada
keyword:dotimes
aka:dotimes
(ver 11.1.2.3 El paquete KEYWORD ) que se expande como un bucle infinito. losdefmacro
macro devuelve el nombre de la macro que se está definiendo, que se puede alimentarshadowing-import
. Por lo tanto, estos nuevosdotimes
símbolos sombrean el estándar (que no debe ser redefinido o ligado léxicamente a otra macro en programas portátiles).Aumentado (2)
Cuando leemos el carácter 8, lo reemplazamos por
(loop)
. Eso significa que lo anterior se lee como(dotimes (i (loop)))
y, por lo tanto, el código nunca termina de calcular el límite superior. Esto afecta a todas las ocurrencias de 8, no solo la del bucle. En otras palabras, 8 realmente significa infinito. Si tiene curiosidad, cuando la tabla de lectura se modifica como anteriormente, el carácter 8 se "termina" y se separa de otros números / símbolos que se leen actualmente:... se lee como:
Puede ejecutar pruebas en Ideone: https://ideone.com/sR3AiU .
fuente
Rubí
Limpiar
Este tipo de bucle for no se usa mucho en Ruby, pero un tutorial típico le dirá que esta es la manera de hacerlo:
Aumentado
El bucle for solo llama
(1..8).each
con el bloque de código dado, por lo que cambiamos ese método:fuente
Haskell
Versión limpia:
Versión aumentada:
Es bastante básico, en realidad: lo único que definimos nuestro propio tipo
T
tal que suenumFromTo
caso es una secuencia infinita, a continuación, utilizar el tipo de morosos para que la ONU-tipo-anotada valores0
y8
se toman como tipoT
.fuente
///
No hay
for
bucles explícitos en ///, pero se pueden simular (se está completando después de todo).Limpiar:
Aumentado:
¿Que esta pasando?
Mientras que el primero programa cuenta frente al 8 a 0, de esta última
/0/0/
norma reemplazará0
por0
hasta la eternidad.fuente
/0/1//1/2/.../7/8//8/8/8
contar en su lugar.Javascript ES6
OK, aquí hay una versión que funciona usando el ES6 para ... de construcción de bucle. Incluso te daré una matriz limpia para que estemos seguros de que no hay asuntos divertidos:
Limpiar
Por supuesto, eso no impide que alguien se meta con el prototipo Array ...
Aumentado
Esto funciona sobrescribiendo el iterador predeterminado para que nunca termine, por lo tanto, bloquea todo en un bucle infinito. El código ni siquiera tiene la oportunidad de ejecutar las cosas dentro del bucle.
fuente
var
el bucle.C ++
Utiliza 2 puntos de extensión:
El programa limpio es el mismo que en la descripción.
fuente
Brainfuck
Imprimo un '0' en cada iteración, solo para que sea fácil contar las iteraciones. Pero cualquier código podría insertarse allí sin cambiar el funcionamiento del bucle.
Limpiar
Pruébalo en línea
La versión aumentada se basa en la implementación común de Brainfuck con celdas de 8 bits. En estas implementaciones, "incremento" es en realidad "incremento (mod 256)". Por lo tanto, para encontrar un bucle que iterará exactamente 8 veces en la versión limpia y sin fin en la versión aumentada, simplemente podemos encontrar una solución para el siguiente sistema de desigualdades.
En este caso, dejamos a = 128, b = 16 y c = 1. Obviamente 128 + 16 * 8 = 256 (y 256 (mod 256) = 0) y 128> 0, y dado que b es par, c + a + b * n es impar para cualquier a + c impar y, por lo tanto, nunca será un múltiplo par de 256 en tales casos. Seleccionamos c = 1 por simplicidad. Por lo tanto, el único cambio que necesitamos es un solo
+
al comienzo del programa.Aumentado
Pruébalo en línea
Lo dejo al OP para determinar si esta entrada está compitiendo. Brainfuck no tiene un bucle for explícito, pero la forma de bucle que utilicé es lo más cercana posible.
++++++++
también es lo más parecido a un literal8
que puedas obtener; He incluido bastantes de esos.La versión limpia casi seguramente constituye un programa típico escrito en este lenguaje, ya que incluso el Brainfuck Hello World más corto conocido depende de una relación de recurrencia modular con el trabajo.
fuente
Haskell
Limpiar
Aumentado
Reemplaza el operador de aplicación de función habitual
$
por uno que repite el ciclo nuevamente cada vez que finaliza. La ejecución de la versión limpia imprime de 0 a 8 y luego se detiene; la versión aumentada imprime de 0 a 8 y luego de 0 a 8 nuevamente, y así sucesivamente.Hago un poco de trampa, porque esa
forM_ [0..8] $ \i -> print i
no es necesariamente la forma "más limpia" de escribir ese bucle en Haskell; muchos Haskellers reducirían el cuerpo del bucle para obtenerforM_ [0..8] print
y luego no hay$
que anular. En mi defensa, copié el código limpio de la respuesta de Cactus , que no necesitaba esa propiedad, por lo que al menos un programador de Haskell escribió ese código sin motivación para agregar innecesariamente el$
!fuente
C ++
Vamos a
x
evaluar a 7. No funciona en C porque requiere un valor l en la asignación e incremento.fuente
Nim
La versión idiomática, usando
countup
:Limpiar
Aumentado
Simple y muy similar a la respuesta de Python que redefine
range
. Redefinimoscountup
, la forma idiomática de Nim de iterar de un int (inclusive) a otro, para dar 8s infinitamente.La versión más interesante, usando el operador de rango
..
:Limpiar
Aumentado
Muy similar a la solución anterior, excepto que redefinimos el operador de rango
..
, que normalmente daría una matriz[1, 2, 3, 4, 5, 6, 7, 8]
, al iterador de antes.fuente
GolfScript
Limpiar
Aumentado
Asigna la función que devuelve n + 1 a la variable 8
fuente
tcl
Normal:
Aumentado:
La idea es redefinir el
incr
comando que se usa para incrementar la variablei
, ¡para que no se incremente!Se puede probar en: http://rextester.com/live/QSKZPQ49822
fuente
Asamblea x86_64
Programa limpio:
El tipo de bucle que usaría cualquier programador de ensamblaje, seguido de una llamada al sistema de salida para no permitir agregar una
jmp loop_start
instrucción después.Programa aumentado:
Además, lo siento si es malo que el programa limpio no tenga un punto de entrada o un
section .text
fuente
JavaScript
Limpiar:
Aumentado:
fuente
C ++
Programa limpio
Un buen bucle normal, iterando de los números 0 a 7.
Programa Aumentado
El preprocesador de C ++ es una característica bastante peligrosa ...
La única línea que tuvimos que agregar fue
#define short bool
. Esto hacei
un booleano en lugar de un entero corto, por lo que el operador de incremento (i++
) no hace nada después dei
llegar a 1. La salida se ve así:fuente