El bucle autodestructivo más corto

61

Su tarea es escribir un programa completo o función que no toma en entrada y ejecuta cualquier tipo de bucle ( while, for, foreach, do, do-while, do-loop, goto, recursividad, etc) que terminará en la causa de un error, lo que significa que el programa debe pararse en ejecución y salida.

Reglas:

  1. El error debe ser un error en tiempo de ejecución, una excepción no controlada o cualquier cosa que haga que el programa finalice por sí mismo.
  2. El error debe producir la detención y la salida del programa sin llamar explícitamente exit;(o equivalente) en algún momento.
  3. Los mensajes como Warning:, Notice:etc., que no provocan que el programa finalice por sí solo no son válidos. Por ejemplo, en PHP, las divisiones por cero producen un Warningmensaje, pero el programa no se detendrá y seguirá ejecutándose, esta no es una respuesta válida.
  4. El bucle debe ejecutar al menos un ciclo completo. En otras palabras, el error puede ocurrir a partir del segundo ciclo y más. Esto es para evitar causar el error usando una sintaxis de código incorrecta: el código debe ser sintácticamente correcto.
  5. El bucle puede ser incluso infinito (ejemplo for(;;);) si respeta las reglas mencionadas anteriormente, pero no debe tomar más de 2 minutos para terminar en un error de tiempo de ejecución.
  6. La recursión sin optimización de llamadas de cola no es válida ( 1 , 2 ).
  7. Este es el por lo que gana el código más corto.
  8. Las lagunas estándar están prohibidas.

Ejemplo de C # ( prueba en línea ):

using System;
public class Program {
    public static void Main() {
        int i;
        int[] n;
        n = new int[5];
        for(i=0; i<7; i++) {
            n[i] = i;
            Console.WriteLine(n[i]);
        }
    }
}


Output: 

0
1
2
3
4
Run-time exception (line 9): Index was outside the bounds of the array.

Stack Trace:

[System.IndexOutOfRangeException: Index was outside the bounds of the array.]
  at Program.Main(): line 9

Tabla de clasificación:

var QUESTION_ID=104323,OVERRIDE_USER=59718;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important;font-family:Arial,Helvetica; font-size:12px}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Gracias a Martin Ender por el fragmento de la tabla de posiciones

Mario
fuente
Para ser claros, la recursión sin TCO se puede usar siempre que el error no tenga que ver con demasiada recursividad, ¿correcto? (Por ejemplo, una función recursiva que
produce
@ETHproductions Fue sugerido por Dennis en el chat: "Puede ser difícil decidir si se ha completado un ciclo completo en este caso [de recursión]. La recursión de cola se ajusta a la factura, pero solo el TCO realmente completa un ciclo si se aborta la ejecución por un error. [...] Diría que la recursividad sin TCO no es válida ".
Mario
En for(a;b;c)d;, ¿después de qué declaración termina el primer ciclo? ¿Es válido interrumpir en la primera evaluación de la cdeclaración?
Hedi
1
@Hedi Aquí está mi humilde opinión (no el OP): todas las entradas deben completar un ciclo completo, lo que significa que deben ingresar a un segundo ciclo; Esto significa que al menos una instrucción se ejecuta por segunda vez. Dado que el orden de ejecución en su ejemplo es a, b, d, c, b, d, c, ..., bes el inicio del ciclo, y debe ejecutarse al menos una segunda vez.
ETHproductions
2
No quiero comenzar ningún problema, pero dado que se supone que el programa (de función para ese caso) no está tomando ninguna entrada, todas las soluciones recursivas que tienen un parámetro no son válidas porque se ingresa un parámetro.
BrainStone

Respuestas:

33

MATL , 5 1 byte

Idea tomada de la respuesta CJam de @ MartinEnder

`

Pruébalo en línea!

`    % Do...while loop
     % Implicit end. The loop continues if the top of the stack is true.
     % After the first iteration, since the stack is empty, the program 
     % implicitly tries to take some non-existing input, and finishes
     % with an error

Versión antigua

2:t"x

Pruébalo en línea!

2:   % Push [1 2]
t    % Duplicate
"    % For each (i.e. do the following twice)
  x  %   Delete top of the stack. Works the first time. The second it tries to
     %   implicitly take some non-existing input, and finishes with an error
Luis Mendo
fuente
3
Funciona sin conexión también. Sin entrada significa que puede asumir una entrada vacía.
Dennis
@Dennis Hm, el programa fuera de línea seguirá esperando la entrada del usuario. La entrada es interactiva, es decir, solicitada según sea necesario en la versión sin conexión. Entonces el programa esperará indefinidamente. ¿No estás seguro de que eso cuenta?
Luis Mendo
No estoy seguro de cómo funciona internamente MATL, pero si lo ejecuta en un entorno incapaz de solicitar entrada (como el backend de TIO), no podrá obtener ninguna entrada. Además, al presionar Ctrl-D o el equivalente dependiente del sistema operativo se debe permitir enviar entradas vacías.
Dennis
35

Python, 16 bytes

El enfoque de división 0 no interesante:

for x in 1,0:x/x

La primera iteración calcula 1 / 1, que funciona bien. La segunda iteración intenta calcular 0 / 0, lo que resulta en un ZeroDivisionErrorlanzamiento.

17 bytes (favorito personal)

i=1
while i:del i

Inicialmente, lo i=1cual es verdadero, por lo que se ingresa el ciclo.

La primera vez que se ejecuta el ciclo, la variable ise elimina.

Esto significa que, la segunda vez, iya no es una variable y, por lo tanto, su evaluación falla conNameError: name 'i' is not defined.


Otra solución de 15 bytes sería def _():_()(nueva línea) _(), porque Python no optimiza la recursividad de cola. Sin embargo, esto viola la regla # 6.

FlipTack
fuente
La solución de 17 bytes también funciona si reemplaza while icon while 1porque intenta eliminar inuevamente;
user6245072
2
@ user6245072 sí, ambos fragmentos se pueden modificar trivialmente para muchas soluciones de trabajo
FlipTack
Puede utilizar su deltruco con un built-in para cortar un poco más: while 1:del id.
DSM
@DSM: del idno funciona. No puede eliminar los builtins de esa manera .
user2357112
18

Jalea , 3 2 bytes

Ṿß

Se suicida al quedarse sin memoria. Localmente lo hace después de ~ 100 segundos.

Pruébalo en línea! (certificado de defunción en el cajón de depuración )

Cómo funciona

Ṿß  Main link. Argument: x. Implicit first argument: 0

Ṿ   Uneval; yield a string representation of x.
 ß  Recursively call the main link.
    Jelly uses TCO, so the first cycle finishes successfully before entering
    the next one.

Las primeras iteraciones producen:

'0'
'”0'
'””,”0'
'””,””,”,,””,”0'
'””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”0'
'””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”,,”,,””,”,,”,,””,””,”,,””,””,”,,””,”,,”,,””,””,”,,””,”0'

Después de eso, se pone muy feo, muy rápido.

Dennis
fuente
¿Cuáles son los límites de memoria de gelatina?
tuskiomi
Jelly no tiene un límite de memoria explícito, así que cualquier cosa que Python pueda abordar. Sin embargo, el uso de memoria se duplica con cada iteración, por lo que esto debería agotar toda la memoria disponible con bastante rapidez.
Dennis
28
Entonces, cada 2 años, podremos ejecutar otra iteración
tuskiomi, el
Entonces, ¿fallará la condición # 5 en una máquina lenta con mucha RAM?
Físico loco
@MadPhysicist Eso es correcto. Sin embargo, este es un problema inherente con los límites de tiempo. El cumplimiento depende en gran medida de qué máquina se ejecuta el programa.
Dennis
13

V , 2 bytes

òl

Pruébalo en línea!

¡Este es el desafío perfecto para V porque ya lo hago todo el tiempo! De hecho, V ni siquiera tiene condicionales, solo tiene funciones que se rompen en caso de error. En este caso, los òmedios "repetir para siempre" y los lmedios "moverse hacia la derecha".

En un búfer vacío (sin entrada), esto se romperá en la primera pasada y no producirá salida. Si no es de entrada, se romperá una vez que avanzamos publicar el último carácter de entrada y salida de la totalidad de la entrada (haciendo esto también un programa de gato)

DJMcMayhem
fuente
3
Espera, lsignifica "moverse a la derecha"? No "mover left"?
Conor O'Brien
1
@ ConorO'Brien sí. En realidad, hay algunas buenas razones históricas para esto.
DJMcMayhem
3
El desafío requiere respuestas para bloquearse en la segunda iteración o más tarde, no en la primera iteración.
Martin Ender
11

JavaScript (ES6), 13 bytes

f=_=>f(_?a:1)

Esta es una función recursiva que funciona bien una vez, luego se lanza ReferenceError: a is not definedy se cierra.

Aquí hay una versión de 15 bytes que no es ES6:

for(i=0;;)i=i.a

Esto funciona bien una vez, luego se tira TypeError: i is undefinedy se cierra.

ETHproducciones
fuente
10

Bash 4.2, 22 bytes

exec $0 $@ $[2**$#%-1]

No funciona en TIO porque tiene Bash 4.3, y el error en el que confío finalmente se solucionó.

Verificación

$ xxd -c 22 -g 22 self-destruct
0000000: 6578656320243020244020245b322a2a2423252d315d  exec $0 $@ $[2**$#%-1]
$ ./self-destruct
Floating point exception

Esto se bloquea una vez que el programa intenta calcular 2 63 mod -1 , que se bloquea en Bash 4.2 y versiones anteriores debido a un error conocido.

Dennis
fuente
10

PHP, 22 21 20 18 bytes

Esto se basa en PHP que le permite a uno dar un nombre de función a una variable e intentar ejecutarlo.

Esto simplemente concatena el nombre de la pifunción dos veces. Esto mata PHP con a Fatal Error: Uncaught Error: Call to undefined function pipi() in [...][...].

while($x.=pi)$x();

Esto funciona de manera similar a mi vieja respuesta.


Respuesta anterior, 20 bytes

PHP le permite incrementar caracteres, utilizando el operador de incremento. Solo funciona en el a-zrango, pero es suficiente.

for($x=pi;;)$x=$x();

Creo que esto cumple con todos los puntos requeridos y el ciclo se ejecuta una vez.

Puede ver si obtendrá el error Fatal error: Function name must be a string.


Cómo funciona esto, paso a paso:

  • Asignar pia $x.
    Como pise está utilizando como una constante, PHP verificará si existe.
    Como no es así, PHP muestra una advertencia que dice Use of undefined constant pi - assumed 'pi'(Básicamente: dado que la constante no existe, se supone que es una cadena)
  • Bucle la primera vez
    • Ejecuta la función $x().
      Como $xtiene el valor pi, ejecutará la función pi().
  • Almacene el valor en $x.
    $xahora tiene π, en lugar depi
  • Bucle por segunda vez
    • Ejecuta la función $x().
      Como $xtiene π, ejecutará la función 3.14159...().
    • π no es una cadena, matando el programa en este punto con a Fatal Error.

¡Gracias a @Titus por encontrar la pi()función, ahorrándome 1 byte!

Ismael Miguel
fuente
Buena, pero no creo que sea válida. Realmente no ejecuta el ciclo una vez. Incrementas $xa abtantes de que el cuerpo del bucle se ejecuta. Podrías arreglar eso incrementando después del ciclo.
aross
Pensé en un enfoque diferente
aross
@ Aross Duh, tienes razón, no era válido. El incremento está en el lugar equivocado. Está funcionando como debería ahora. Puedes intentar correr for($x=abs;;++$x)echo$x,$x();para probar. Debería mostrarlo abs0abt Fatal error[...]. O similar.
Ismael Miguel
1
Podrías usar en pilugar de abs. Eso ni siquiera da una advertencia antes de arrojar lo fatal.
Tito el
@Titus ¡Olvidé por completo esa función! Sé que la función _está definida en algunos sistemas, pero no es confiable. Pero gracias por encontrar eso!
Ismael Miguel
10

GNU sed , 15 13 5 bytes

-2 Gracias a seshoumara
-8 Gracias a zeppelin

H;G;D
  1. Agrega una nueva línea y el espacio de retención al espacio del patrón.
  2. Agrega una nueva línea y el espacio del patrón al espacio de espera.
  3. Elimina hasta la primera línea nueva y comienza de nuevo.

Esto rápidamente se queda sin memoria:

$ time (echo|sed 'H;G;D')
sed: couldn't re-allocate memory

real    0m1.580s
user    0m0.545s
sys     0m1.012s
Riley
fuente
Hola, ¿qué tal s:a\?:&a:g? Es 1 byte menos y duplica el tamaño del patrón por iteración también.
seshoumara
@seshoumara No creo que coincida con nada cuando el espacio del patrón esté vacío, por lo que nunca será el primer reemplazo.
Riley
@seshoumara echo -n | sed 's:a\?:&a:g'y no obtuvo salida. Sería lo mismo sed 's::a:'que no coincidiría con nada.
Riley
Con echo -nabsolutamente nada se pasa a sed, pero sed no puede comenzar sin entrada por diseño. Verifique este metaenlace para ver que esa echo|sedes la forma aceptada de iniciar sed para los desafíos que invocan una regla de no entrada.
seshoumara
@seshoumara Pensé que aún le daría una cadena vacía. Eso parece funcionar entonces. ¡Gracias!
Riley
9

R, 22 25 22 20 18 bytes

Editar: Gracias a @Mego por señalar que R no admite la optimización de llamadas de cola.

Edit4: encontré una solución aún más corta que es simple pero bastante compleja.

repeat(ls(T<-T-1))

La respuesta utiliza la variable de verdad booleana incorporada, Tque se disminuye indefinidamente en el ciclo de repetición. La función ls()se llama cada iteración que enumera todos los objetos en el entorno actual. Sin embargo, el primer argumento nameespecifica desde qué entorno desde el cual listar objetos. De la documentación R encontramos que:

El argumento de nombre puede especificar el entorno del que se toman los nombres de los objetos en una de varias formas: como un entero (la posición en la searchlista); como el nombre de la cadena de caracteres de un elemento en la lista de búsqueda; o como explícito environment(incluido el uso sys.framepara acceder a las llamadas a funciones actualmente activas).

Esto significa principalmente que en la primera iteración ejecutamos ls(-1)lo que devolvería character(0)(estándar cuando se intenta acceder al everything-except-the-firstelemento inexistente de cualquier objeto de tipo de carácter). Durante la segunda iteración, Tse disminuye por dos y posteriormente llamamos, lo ls(-3)que a su vez devuelve el error:

Error in as.environment(pos) : invalid 'pos' argument

Esto se debe a que intentamos enumerar el everything-except-the-thirdelemento, pero el entorno local solo contiene la variable Ten este punto (como tal, ls()devolvería una lista de longitud 1en esta iteración) y se devuelve un error.

Billywob
fuente
1
Eso no parece que la recursividad se haga con la optimización de la cola de llamadas, si hay un límite de recursión.
Mego
@Mego Después de investigar un poco, descubrí que R no admite la optimización de llamadas de cola, por lo que esta respuesta no es válida (nunca antes había escuchado sobre el concepto). Cambiará a una respuesta válida en un momento.
Billywob
9

Befunge-93, 3 bytes (posiblemente 1 o 0)

!%!

Pruébalo en línea!

En la primera iteración del bucle, la pila está vacía, lo que equivale a todos los ceros. La !operación (no) convierte la parte superior de la pila en 1, y la %operación (módulo) calcula 0 mod 1, dejando 0. La siguiente !operación convierte ese 0 en 1 antes de que el contador del programa se enrolle y comience el ciclo nuevamente.

En la segunda iteración, las primeras !operaciones convierten el 1 que ahora está en la parte superior de la pila a 0. La %operación calcula 0 mod 0, que produce una división por cero error en el intérprete de referencia, y así termina el programa.

También está la respuesta más aburrida de 1 byte, aunque no estoy seguro de si esto se considera válido.

"

Pruébalo en línea!

Este "comando inicia una cadena, por lo tanto, cada espacio en el resto de la línea se inserta en la pila hasta que el contador del programa se enrolla y encuentra el "cierre de la cadena nuevamente. Luego tendrá que ajustarse una segunda vez para repetir el proceso comenzando otra cadena y empujando otros 79 espacios en la pila. Eventualmente, esto se quedará sin memoria (el comportamiento del intérprete de referencia) o producirá un desbordamiento de la pila.

Ahora, si realmente quiere impulsar las reglas, técnicamente también existe una solución de cero bytes.


Si se toma esta decisión en el sentido de que cualquier intérprete define el lenguaje (como muchos aquí hace), entonces podemos suponer por un momento que el lenguaje Befunge se define por este intérprete . Y una de las "características" de ese intérprete es que empuja un valor Indefinido en la pila para cada bucle del campo de juego cuando ejecuta un programa en blanco. Dado el tiempo suficiente, eventualmente se quedará sin memoria.

La rapidez con que eso ocurra dependerá de la velocidad de la computadora, la memoria disponible y el navegador utilizado. En mi máquina descubrí que Microsoft Edge funcionaba mejor, pero aun así era "solo" usando 500 MB después de dos minutos. No fue hasta alrededor de los quince minutos (con varios gigabytes utilizados) que Edge decidió matar el proceso y actualizar la pestaña. Por lo tanto, es poco probable que sea por debajo del límite de tiempo de dos minutos, pero con las condiciones adecuadas que no estarían necesariamente fuera de discusión.

James Holderness
fuente
8

FALSO, 8 bytes

Realmente me gusta este lenguaje.

1[$][.]#

Esto empuja a 1, luego se repite [$][.]#mientras $es verdadero (duplicar la parte superior de la pila) y ( .) lo genera. Este intérprete se bloquea después de que 1se imprime el single (evidencia de que el bucle se ejecuta al menos una vez). Parece ser un error en este intérprete. El siguiente programa de 9 bytes debería funcionar en todos los intérpretes compatibles:

1[$][..]#
Conor O'Brien
fuente
También deberías probar DUP, que es básicamente un superconjunto de FALSE. Eso es lo que solía hacer RETURN.
Mama Fun Roll
@MamaFunRoll oh sí, ¡olvidé que hiciste RETURN! Tengo que probar ese. : D
Conor O'Brien
@MamaFunRoll Me encanta DUP, acabo de escribir un intérprete de DUP y estoy jugando con él.
ML
@ ConnorO'Brien: Diría que su primera solución debería bloquear a cualquier intérprete. Acabo de hacer una depuración con mi propio intérprete, y es obvio que el primero .vacía la pila de datos, mientras que en el segundo bucle $intenta duplicar el elemento superior de la pila vacía, lo que debería conducir a un error (bueno, mi intérprete hace ) La segunda versión no debería ser válida porque ni siquiera termina el primer ciclo porque ya intenta acceder a la pila vacía antes de tiempo.
ML
Para su segundo ejemplo, aquí hay un volcado de depuración a todo color de mi intérprete DUP. es obvio una vez que veas cómo funcionan la pila de datos (ds) y la pila de retorno (rs), aunque esta última no es transparente en FALSO.
ML
8

C, 21 bytes

i;f(){for(;1/!i++;);}

Aquí iestá garantizado comenzar como 0.

Se puede confirmar que esto se ejecuta una vez así:

i;f(){for(;1/!i++;)puts("hi");}
main(){f();}

Lo cual, en mi máquina, resulta en:

llama@llama:...code/c/ppcg104323loop$ ./a.out 
hi
zsh: floating point exception (core dumped)  ./a.out

La solución recursiva más corta que puedo encontrar es de 22 bytes :

f(i){f(i-puts(""-i));}

gccsolo elimina la llamada de cola en -O2o más alto, en ese punto necesitamos llamar a una función como putspara evitar que todo se optimice. Confirmación de que esto funciona:

llama@llama:...code/c/ppcg104323loop$ cat loop.c       
main(){f();}
f(i){f(i-puts(""-i));}
llama@llama:...code/c/ppcg104323loop$ gcc -O2 -S loop.c 2>/dev/null
llama@llama:...code/c/ppcg104323loop$ grep call loop.s
    call    puts
    call    f

El siguiente es un programa completo, que supone que se llama sin argumentos de línea de comando, a 22 bytes :

main(i){for(;1/i--;);}

que es equivalente a la función de la misma longitud:

f(i){for(i=1;1/i--;);}
Pomo de la puerta
fuente
¿Una función como esta se trata como principal? Si es así, el primer argumento es la longitud de la lista de argumentos (que es 1, el nombre que se usó para llamarlo).
Riley
O bien, el registro de argumentos todavía tiene el valor que estaba allí desde que se llamó a main.
Riley
@Riley Ahh, la última teoría parece ser el caso, como lo demuestra el hecho de que el número aumenta a medida que se agregan argumentos de línea de comando. Gracias por la idea!
Pomo de la puerta
No estaba seguro de cómo lo estabas llamando en mi primera suposición, pero debería ser el mismo que el primer argumento de la función que llama f.
Riley
Sí, tio
Riley
6

MATLAB, 18 bytes

Esto se puede ejecutar como un script:

for j=1:2;j(j);end

La primera iteración está bien, ya que j(1)es justa 1. La segunda iteración se bloquea con un error de matriz fuera de límites, ya que j(2)excede las dimensiones de j, que es una matriz 1x1.

Esto también se puede ejecutar como un script, pero solo funciona la primera vez que lo ejecuta. Aún así, es un abuso lo suficientemente hilarante de las constantes predefinidas de MATLAB que pensé que lo incluiría. También es de 18 bytes.

while i/i;i={};end

Cuando se ejecuta en un espacio de trabajo en el que la variable iaún no se ha definido, esto supone que ies la unidad imaginaria, entonces i/i = 1. En el primer bucle, la asignación i={}crea una matriz de celdas vacía llamada i. En la segunda iteración, el ciclo sale con "Operador indefinido '/' para argumentos de entrada de tipo 'celda'".

MattWH
fuente
¡Ambos son increíbles! Usted probablemente sabe esto, pero j(2)normalmente dará una matriz de 2 por 2 con0+1i
Stewie Griffin
¡Gracias! Eso es cierto en Octave pero no en MATLAB, creo
MattWH
6

Perl 6 , 13 bytes

loop {5[$++]}

Indiza un literal entero en un bucle infinito.
Se basa en el hecho de que en los valores escalares, la sintaxis de indexación de matriz se puede usar con el índice 0(devolviendo el valor en sí), pero arroja un Index out of rangeerror para cualquier otro índice.

smls
fuente
6

QBasic, 17 bytes

Este código es muy raro.

DO
i=11+a(i)
LOOP

Cómo funciona

En QBasic, las variables se preinicializan. Una variable regular sin ningún tipo de sufijo, como iaquí, se preinicializa a cero.

Excepto si intenta subíndice en esa variable como una matriz ... en cuyo caso, es una matriz de 11 ceros. *

Por primera vez a través del ciclo, por lo tanto, ies 0y aes una matriz. a(i)da el elemento cero de la matriz (que es 0). Todo bien y bien. Nos ponemos ia 11y bucle. Pero ahora 11no es un índice válido para la matriz a, y el programa se detiene con Subscript out of range.

Una versión de 19 bytes que muestra mejor lo que está sucediendo:

DO
?a(i)
i=i+1
LOOP

Esto se imprimirá 0once veces antes de equivocarse.


* Conceptualmente, es una matriz de 10 elementos. La mayoría de las cosas en QBasic están indexadas en 1, pero las matrices no, posiblemente por razones de implementación. Para que las cosas funcionen como se espera para los programadores, QBasic agrega una entrada adicional para que pueda usar los índices 1 a 10. Sin embargo, el índice 0 sigue siendo perfectamente accesible. Imagínate.

DLosc
fuente
QBasic y arrays, ¿dónde se detiene la diversión?
steenbergh
Dado que el error no tiene que estar en el segundo ciclo, ¿no podría hacerlo i=1+a(i)?
Quelklef
@Quelklef No, tendrías que hacer i=i+1+a(i). De lo contrario, el índice nunca sube 1, lo cual no es un error.
DLosc
@DLosc Oh, tienes razón.
Quelklef
5

Haskell, 15 bytes

f(a:b)=f b
f"a"

f"a"se ejecuta recursivamente a través de la cadena "a" al soltar el primer carácter y finalmente falla al final con una Non-exhaustive patterns in function fexcepción, porque fsolo se define para cadenas no vacías.

nimi
fuente
5

C #, 71 38 bytes

Dado que proporcionó un ejemplo en C # aquí, otra versión de golf

Y gracias a pinkfloydx33

void c(){checked{for(uint i=1;;i--);}}

Más corto que Parse.ToString()e incluso que Parse($"{c--}") me tiró mentalmente checkedpor ser una palabra clave demasiado larga. Resistente, ciertamente es más corto queParse(c.ToString())

Respuesta original

class p{static void Main(){for(int c=0;;c--)uint.Parse(c.ToString());}}

Esto iniciará c=0luego disminuirlo, cuando c=-1la uint.Parseva a causar una:

Unhandled Exception: System.OverflowException: Value was either too large or too small for a UInt32.

Versión sin golf y verificar que el ciclo se ejecuta al menos una vez

class p {
    static void Main() {
        for(int c=0;;c--) {
            System.Console.Write(c);
            uint.Parse(c.ToString());
        }
    }
}
MrPaulch
fuente
for(int c=0;;)uint.Parse($"{c--}");
pinkfloydx33
1
checked{for(uint c=1;;)c--;}
pinkfloydx33
Ok, wow! ¡No sabía sobre la taquigrafía '$'!
MrPaulch
4

CJam , 4 bytes

1{}g

Pruébalo en línea!

La primera iteración del {}gbucle vacío muestra el 1, que le dice que continúe. La segunda iteración intenta hacer aparecer otro condicional, pero la pila está vacía, por lo que el programa se bloquea.

Martin Ender
fuente
4

Ensamblado x86 (sintaxis AT&T), 40 bytes

f:
mov $1,%eax
A:
div %eax
dec %eax
je A

Declara una función f que divide 1 por 1 en su primera iteración y luego intenta dividir 0 por 0 y errores.

poi830
fuente
Puede guardar 4 bytes cambiando a la sintaxis Intel :)
mriklojn
66
Generalmente calificamos el ensamblaje por el tamaño del código de bytes generado, no por las instrucciones legibles por humanos.
Dennis
@Dennis asamblea ensamblada es lenguaje de máquina. pero sí, esto podría afirmarse mucho más corto en forma de lenguaje de máquina.
Jasen
Deshágase de la etiqueta f y el mov. Cambia dec y div, y podrás deshacerte de más.
Más claro
4

CJam, 4 bytes

P`:~

P`genera la cadena 3.141592653589793. :~evalúa cada personaje. 3es un código válido en CJam que simplemente devuelve 3. En la siguiente iteración, .causa un error porque requiere un dígito o un operador que lo siga.

jimmy23013
fuente
4

Rubí, 14 bytes

loop{$./=~$.}

Salidas por ZeroDivisionError: divided by 0

$. The current input line number of the last file that was read

Ruby Docs

Jatin Dhankhar
fuente
4

> <> , 3 bytes

!]!

Pruébalo aquí!

Explicación

!    skip next instruction
 ]   close stack (crash)
  !  skip next instruction (jumping to close stack)
Redstarcoder
fuente
4

Lote, 22 20 bytes

:a
set i=%i%1
goto a

Explicación

Este es un bucle infinito que agrega un 1a una cadena inicialmente vacía. Eventualmente, esto pasará la longitud máxima de cadena de 8192 y se bloqueará. En mi máquina, esto lleva unos 30 segundos.

Algo oscuro
fuente
¡Agradable! Puede guardar 2 bytes utilizando terminaciones de línea Unix.
briantist
Puede usar% 0, que es el nombre del archivo en lugar de la etiqueta y goto.
YourDeathIsComing
No estaba seguro si eso rompió la regla de recursión de la cola.
Algo
4

JavaScript, 9 bytes

for(;;i);

Esto se ejecuta una vez, luego arroja lo ReferenceError: i is not definedque detiene el bucle.

// With a console.log(1) to see that it runs once.
for(;;i)console.log(1);


Tomando lo siguiente como ejemplo, ¿es el <increment>final del primer ciclo o el comienzo del segundo ciclo?

0:for(<init>;<test>;<increment>)
1:{
2:  <statement>;
3:}

1 / lo veo

Después de pasar de las líneas 0 a la línea 3 y luego volver a la línea 0, parece que se ha completado un ciclo completo.
Eso haría <increment>el comienzo del segundo ciclo.
- Primer ciclo: <init>-> <test>-> <statement>
- Segundo ciclo: <increment>-> <test>-><statement>

2 / Whileequivalente

0:<init>;
1:while(<test>)
2:{
3:  <statement>;
4:  <increment>;
5:}

En este equivalente whileal <increment>es el final del primer ciclo y se siente como si fuera el mismo con el for.
Eso haría <increment>el final del primer ciclo.
- Primer ciclo: <test>-> <statement>-> <increment>
- Segundo ciclo: <test>-> <statement>-><increment>

3 / Una declaración se encuentra dos veces

Un ciclo completo se completa cuando una declaración se encuentra dos veces.
La primera declaración encontrada dos veces es <test>.
Eso haría <increment>el final del primer ciclo.
- Primer ciclo: <test>-> <statement>-> <increment>
- Segundo ciclo: <test>-> <statement>-><increment>

4 / Es una configuración

El <init>solo está configurando lo que sea necesario para el primer ciclo.
El <increment>solo está configurando lo que sea necesario para el segundo ciclo.
Eso haría <increment>el comienzo del segundo ciclo.
- Primer ciclo: <init as a setup>-> <test>-> <statement>
- Segundo ciclo: <increment as a setup>-> <test>-><statement>


La especificación de idioma ECMAScript® 2016

Tiempo de ejecución de for(<init>;<test>;<increment>)<statement>;

Deje que varDcl sea el resultado de la evaluación <init>.
ReturnIfAbrupt (varDcl).
Regreso ? ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelset).

Hay tres formas, así que tomé la más corta aquí, no hay diferencia:
- Sea lo <init>que sea, no es parte de la primera iteración.
- Lo relevante es en ForBodyEvaluation.

Los detalles de ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelset)

0 Sea V indefinido.
1 Realizar? CreatePerIterationEnvironment (perIterationBindings).
2 Repita
3 Si no está [vacío], entonces
4 Sea testRef el resultado de la evaluación <test>.
5 Deja que testValue sea? GetValue (testRef).
6 Si ToBoolean (testValue) es falso, devuelva NormalCompletion (V).
7 Deje que el resultado sea el resultado de la evaluación <statement>.
8 Si LoopContinues (result, labelSet) es falso, devuelva Completion (UpdateEmpty (result, V)).
9 Si el resultado. [[Valor]] no está vacío, deje que V sea el resultado. [[Valor]].
10 Realizar? CreatePerIterationEnvironment (perIterationBindings).
11 Si no está [vacío], entonces
12 Sea incRef el resultado de la evaluación <increment>.
13 Realizar? GetValue (incRef).

6 / Lo veo

Un ciclo completo una ejecución completa de la parte de repetición.
Eso haría <increment>el final del primer ciclo.
- Primer ciclo: <test>-> <statement>-> <increment>/ En otras palabras, de la línea 3 a la línea 13
- Segundo ciclo: <test>-> <statement>-> <increment>/ En otras palabras, de la línea 3 a la línea 13

7 / Un ciclo es una iteración

Un ciclo comienza con CreatePerIterationEnvironment.
Entonces, cuando CreatePerIterationEnvironmentse encuentra, comienza un nuevo ciclo, terminando así el anterior.
Eso haría <increment>el comienzo del segundo ciclo.
- Primer ciclo: <test>-> <statement>/ En otras palabras, desde la línea 1 a la línea 9
- Segundo ciclo: <increment>-> <test>-> <statement>/ En otras palabras, desde la línea 10 en bucle hasta la línea 9


¿Es el <increment>final del primer ciclo o el comienzo del segundo ciclo?

La explicación correcta es 6 o 7.

Hedi
fuente
8
Creo que estoy más inclinado a atribuir el incremento al final de la primera iteración, en lugar de al comienzo de la segunda iteración o a ninguna de ellas. Supongo que esto es una ambigüedad de la pregunta.
1
Como for(a;b;c)d;es más o menos equivalente a a;while(b){d;c;}, me inclino a decir que el error todavía se produce en la primera iteración (antes de que se verifique la condición del bucle por segunda vez).
ETHproductions
@Hurkyl La primera iteración comienza con la inicialización, por lo que creo que el incremento debería ser el comienzo de la segunda iteración.
Hedi
44
Si lee la especificación , puede ver que la operación de incremento es la última parte de la iteración y, como tal, todavía pertenece a la primera iteración.
Nit
3
@Hedi No veo cómo eso es relevante en absoluto. La operación de incremento es muy claramente una parte de la primera ejecución del ciclo. Para reformular, cuando se llama a la operación de incremento, el ciclo no ha terminado una sola ejecución completa.
Nit
4

INTERCAL , 12 bytes

(1)DO(1)NEXT

Pruébalo en línea!

NEXTes el comando de flujo de control principal de INTERCAL-72. (Se introdujeron revisiones posteriores COME FROM, que se hicieron más famosas, pero no estaba en la versión original del lenguaje; y todas las implementaciones de INTERCAL terminadas conozco el soporte NEXTpara la compatibilidad con versiones anteriores, con todos menos uno habilitando el soporte por defecto. Entonces No siento la necesidad de nombrar INTERCAL-72 específicamente en el título).

Cuando se usa NEXTpara formar un bucle, se supone que debe usar RESUMEo FORGETpara liberar el espacio que usa para recordar dónde ha estado el programa; RESUMEretroactivamente convierte el elemento NEXTen algo parecido a una llamada de función (aunque puede regresar de funciones distintas a la que está) mientras FORGETque lo convierte en algo más similar a una declaración GOTO. Si no lo hace (y este programa no lo hace), el programa se bloqueará después de 80 iteraciones (este comportamiento se especifica realmente en la especificación INTERCAL).

Es algo ambiguo si esto cuenta como una recursión ilimitada (no permitida en la pregunta); ciertamente puede usar este tipo de NEXTpara implementar una llamada a la función, en cuyo caso sería efectivamente una función recursiva, pero aquí no hay suficiente información para determinar si estamos haciendo una llamada a la función o no. Al menos, estoy publicando esto de todos modos porque no viola las reglas inequívocamente, y una implementación INTERCAL que optimizó la "llamada de cola" no solo violaría la especificación, sino que también causaría la ruptura de la mayoría de los programas existentes, porque al regresar de la "función incorrecta" es la forma principal de hacer el equivalente de una declaración IF.

Aquí está el mensaje de error resultante, generado por C-INTERCAL:

ICL123I PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON
    ON THE WAY TO 1
        CORRECT SOURCE AND RESUBNIT

(Tenga en cuenta que la segunda línea está sangrada con una pestaña, y la tercera con ocho espacios. Esto parece correcto en un terminal, o en casi cualquier programa que tenga tabulaciones en múltiplos de 8. Sin embargo, Markdown tiene tabulaciones en múltiplos de cuatro, violando los supuestos que la mayoría de los programas más antiguos hacen acerca de las pestañas, por lo que el mensaje de error está un poco malformado aquí).


fuente
¿El error realmente dice CORRECT SOURCE AND RESUBNIT? ¿Como en un error tipográfico en el mensaje de error C-INTERCAL original?
Andrakis
1
@Andrakis: Sí, lo hace. Ese error tipográfico se ha conservado cuidadosamente durante años.
3

Pyth, 3 bytes

W1w

Pruébalo en línea.

W1es solo while 1:en Python. El cuerpo del bucle imprime una línea leída de STDIN, que se bloquea para la segunda iteración cuando el código se ejecuta con una entrada vacía.

Si los bucles que usan #(bucle hasta error) están prohibidos (supongo que sí), creo que esto es lo más corto que puede ser.

PurkkaKoodari
fuente
3

Python 3, 29 bytes

i=1
def x(n):del i;x(i)
x(i)

Muy simple En la segunda llamada a x, no estoy allí, y Python se queja al respecto.

python-b5
fuente
3

Laberinto , 3 bytes

#(/

Pruébalo en línea!

Como la mayoría de los lenguajes 2D, Labyrinth no tiene construcciones de bucle explícitas. En cambio, cualquier código que se presente de manera tal que se ejecute varias veces seguidas es un bucle en estos idiomas. Para el caso de Labyrinth, un programa lineal simple actúa como un bucle, porque el puntero de instrucción rebotará hacia adelante y hacia atrás. Si el programa es abc(para algunos comandos a, by c), entonces la ejecución real será abcbabcbabcb...para que se ejecute abcben un bucle infinito.

En cuanto a por qué este programa en particular se bloquea en la segunda iteración de este ciclo, esto es lo que hacen los comandos individuales. Tenga en cuenta que la pila de Labyrinth contiene una cantidad infinita implícita de ceros en la parte inferior:

#   Push stack depth.   [... 0]
(   Decrement.          [... -1]
/   Divide.             [... 0]
(   Decrement.          [... -1]
#   Push stack depth.   [... -1 1]
(   Decrement.          [... -1 0]
/   Divide.             Crashes with division-by-zero error.
Martin Ender
fuente
3

Bash, 11 (límite no competidor)

exec $0 1$@

Este script se ejecuta recursivamente, agregando 1los argumentos pasados ​​en cada iteración. Creo que esto cuenta como TCO porque el ejecutivo reutiliza el espacio del proceso pero no se come la pila. No está en competencia ya que tardó unos 10 minutos en ser asesinado en mi máquina: YMMV.

Trauma digital
fuente
1
exec $0 1$@$@ termina mucho más rápido pero tiene dos caracteres más.
Jasen
3

cmd, 34 bytes

for /l %i in (0,1,10) do color %i0

Esto pasará %ide 0 a 10. El colorcomando (antiguo) aceptará felizmente cualquier argumento que tenga 2 dígitos hexadecimales. Con el argumento 100fallará, imprimiendo el mensaje de ayuda y configurando ERRORLEVELa 1.

Prueba de que el ciclo se ejecuta al menos una vez: ¡El color de su caparazón será diferente!

MrPaulch
fuente