Loop auto-destrutivo mais curto


61

Sua tarefa é escrever um programa completo ou função que não leva de entrada e executa qualquer tipo de loop ( while, for, foreach, do, do-while, do-loop, goto, recursão, etc) que vai acabar em causar um erro, o que significa que o programa deve parar-se em execução e Saída.

Regras:

  1. O erro deve ser um erro de tempo de execução, exceção não tratada ou qualquer coisa que faça com que o programa termine sozinho.
  2. O erro deve produzir a parada e a saída do programa sem chamar explicitamente exit;(ou equivalente) em algum momento.
  3. Mensagens como Warning:, Notice:etc, que não fazem com que o programa termine por si só não são válidas. Por exemplo, nas divisões do PHP por zero, produz uma Warningmensagem, mas o programa não para e continua sendo executado, essa não é uma resposta válida.
  4. O loop deve executar pelo menos um ciclo completo. Em outras palavras, o erro pode ocorrer a partir do segundo ciclo e depois. Isso é para evitar causar o erro usando a sintaxe de código incorreta: o código deve estar sintaticamente correto.
  5. O loop pode ser infinito (exemplo for(;;);) se respeitar as regras acima mencionadas, mas não deve demorar mais de 2 minutos para terminar em um erro em tempo de execução.
  6. A recursão sem a otimização da chamada de cauda é inválida ( 1 , 2 ).
  7. Isso é então o código mais curto vence.
  8. As brechas padrão são proibidas.

Exemplo de C # ( teste online ):

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

Entre os melhores:

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>

Agradecimentos a Martin Ender pelo snippet da tabela de classificação


Só para esclarecer, a recursão sem TCO pode ser usada desde que o erro não tenha a ver com muita recursão, correto? (Por exemplo, uma função recursiva que erros no segundo recursão)
ETHproductions

@ETHproductions Foi sugerido por Dennis no bate-papo: "Pode ser difícil decidir se um ciclo completo foi concluído neste caso [de recursão]. A recursão da cauda meio que se encaixa na conta, mas apenas o TCO realmente conclui um ciclo se a execução for abortada. por um erro. [...] Eu diria que a recursão sem o TCO é inválida. "
23716 Mario Mario

Em for(a;b;c)d;, depois da declaração wich termina o primeiro ciclo? É válido interromper a primeira avaliação da cdeclaração?
Hedi

11
@Hedi Aqui está minha humilde opinião (não o OP): todas as entradas devem concluir um ciclo completo, o que significa que devem entrar em um segundo ciclo; isso significa que pelo menos uma instrução é executada uma segunda vez. Como a ordem de execução no seu exemplo é a, b, d, c, b, d, c, ..., bé o início do ciclo e deve ser executada pelo menos uma segunda vez.
ETHproductions

2
Não quero iniciar nenhum problema, mas como o programa (de função) não deve receber nenhuma entrada, todas as soluções recursivas que possuem um parâmetro são inválidas porque um parâmetro é inserido.
BrainStone

Respostas:


33

MATL , 5 1 byte

Ideia retirada da resposta CJam de @ MartinEnder

`

Experimente online!

`    % 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

Versão antiga

2:t"x

Experimente online!

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

3
Funciona offline também. Nenhuma entrada significa que você pode assumir uma entrada vazia.
Dennis

@Dennis Hm, o programa offline continuará aguardando a entrada do usuário. A entrada é interativa, ou seja, solicitada conforme necessário na versão offline. Portanto, o programa aguardará indefinidamente. Não tem certeza do que conta?
Luis Mendo

Não sei exatamente como o MATL funciona internamente, mas se você o executar em um ambiente incapaz de solicitar entrada (como o back-end do TIO), ele não poderá obter nenhuma entrada. Além disso, pressionar Ctrl-D ou o equivalente dependente do SO deve poder enviar entrada vazia.
Dennis

35

Python, 16 bytes

A abordagem não interessante da divisão 0:

for x in 1,0:x/x

A primeira iteração calcula 1 / 1, o que funciona bem. A segunda iteração tenta calcular 0 / 0, resultando em um ZeroDivisionErrorlançamento.

17 bytes (favorito pessoal)

i=1
while i:del i

Inicialmente, i=1como é verdade, o loop é inserido.

A primeira vez que o loop é executado, a variável ié excluída.

Isso significa que, pela segunda vez, inão é mais uma variável e, portanto, sua avaliação falha comNameError: name 'i' is not defined.


Outra solução de 15 bytes seria def _():_()(nova linha) _(), porque o Python não otimiza a recursão da cauda. No entanto, isso viola a regra 6.


A solução 17 bytes também funciona se você substituir while icom while 1porque tenta apagar inovamente;
user6245072

2
@ user6245072 sim, ambos os trechos podem ser trivialmente modificados para os lotes de soluções de trabalho
FlipTack

Você pode usar seu deltruque com um built-in para raspar um pouco mais: while 1:del id.
DSM


18

Geléia , 3 2 bytes

Ṿß

Se mata ficando sem memória. Faz isso localmente após ~ 100 segundos.

Experimente online! (atestado de óbito na gaveta de depuração )

Como 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.

As primeiras iterações produzem:

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

Depois disso, fica muito feio, muito rápido.


Quais são os limites de memória da geléia?
Tuskiomi

O Jelly não tem um limite de memória explícito, portanto, o que o Python puder endereçar. O uso da memória dobra a cada iteração, portanto, isso deve esgotar toda a memória disponível rapidamente.
Dennis

28
Portanto, a cada 2 anos, seremos capazes de executar outra iteração
tuskiomi

Então, falhará a condição # 5 em uma máquina lenta com muita RAM?
Mad Physicist

@MadPhysicist Isso está correto. Este é um problema inerente aos limites de tempo. A conformidade depende muito de qual máquina o programa é executado.
Dennis #

13

V , 2 bytes

òl

Experimente online!

Este é o desafio perfeito para o V, porque eu já faço isso o tempo todo! De fato, V nem sequer tem condicionais, apenas possui funções que quebram em um erro. Nesse caso, os òmeios "repetem para sempre" e os lmeios "se movem para a direita".

Em um buffer vazio (sem entrada), isso será interrompido na primeira passagem e não produzirá saída. Se não é de entrada, ele vai quebrar uma vez que mover postar o último caractere de entrada e saída de toda a entrada (fazendo isso também um programa de gato)


3
Espere, lsignifica "mover para a direita"? Não é "move left"?
Conor O'Brien

11
@ ConorO'Brien sim. Na verdade, existem algumas boas razões históricas para isso.
DJMcMayhem

3
O desafio requer respostas para travar na segunda iteração ou posterior, não na primeira iteração.
Martin Ender

11

JavaScript (ES6), 13 bytes

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

Essa é uma função recursiva que funciona bem uma vez, depois lança ReferenceError: a is not definede sai.

Aqui está uma versão não-ES6 de 15 bytes:

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

Isso funciona bem uma vez, depois lança TypeError: i is undefinede sai.


10

Bash 4.2, 22 bytes

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

Não funciona no TIO porque possui o Bash 4.3, e o bug em que estou confiando foi finalmente corrigido.

Verificação

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

Isso trava quando o programa tenta calcular 2 63 mod -1 , que trava no Bash 4.2 e em versões anteriores devido a um bug conhecido.


10

PHP, 22 21 20 18 bytes

Isso depende do PHP, que permite atribuir um nome de função a uma variável e tentar executá-lo.

Isso simplesmente concatena o nome da pifunção duas vezes. Isso mata o PHP com um Fatal Error: Uncaught Error: Call to undefined function pipi() in [...][...].

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

Isso funciona de maneira semelhante à minha resposta antiga.


Resposta antiga, 20 bytes

O PHP permite incrementar caracteres usando o operador de incremento. Funciona apenas no a-zintervalo, mas é suficiente.

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

Eu acredito que isso preenche todos os pontos necessários e o loop é executado uma vez.

Você pode ver se, porque você receberá o erro Fatal error: Function name must be a string.


Como isso funciona, passo a passo:

  • Atribuir pia $x.
    Como piestá sendo usado como uma constante, o PHP verificará se existe.
    Como não existe, o PHP mostra um aviso dizendo Use of undefined constant pi - assumed 'pi'(Basicamente: como a constante não existe, é considerado uma string)
  • Loop pela primeira vez
    • Executar a função $x().
      Como $xtem o valor pi, ele executará a função pi().
  • Armazenar o valor em $x.
    $xagora tem π, em vez depi
  • Loop pela segunda vez
    • Executar a função $x().
      Como $xtem π, ele executará a função 3.14159...().
    • π não é uma string, matando o programa neste momento com a Fatal Error.

Obrigado a @Titus por encontrar a pi()função, economizando 1 byte!


Legal, mas não acho que seja válido. Realmente não executa o loop uma vez. Você incrementar $xa abtantes de o corpo do laço é executado. Você pode corrigir isso incrementando após o loop.
Aross 27/16 /

Pensei em uma abordagem diferente
aross

@aross Duh, você está certo, não era válido. O incremento está no lugar errado. Está funcionando como deveria agora. Você pode tentar executar o for($x=abs;;++$x)echo$x,$x();teste. Deve mostrar abs0abt Fatal error[...]. Ou similar.
Ismael Miguel

11
Você poderia usar em pivez de abs. Isso nem gera um aviso antes de lançar o fatal.
Titus

@ Titus eu esqueci completamente essa função! Eu sei que a função _é definida em alguns sistemas, mas não é confiável. Mas obrigado por encontrar isso!
Ismael Miguel

10

GNU sed , 15 13 5 bytes

-2 Graças a seshoumara
-8 graças a zeppelin

H;G;D
  1. Anexa uma nova linha e o espaço de espera ao espaço do padrão.
  2. Anexa uma nova linha e o espaço do padrão ao espaço de espera.
  3. Exclui até a primeira nova linha e inicia novamente.

Isso fica rapidamente sem memória:

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

real    0m1.580s
user    0m0.545s
sys     0m1.012s

Oi, como sobre s:a\?:&a:g? É 1 byte a menos e também dobra o tamanho do padrão por iteração.
seshoumara

@seshoumara Não acho que isso corresponda a nada quando o espaço do padrão estiver vazio, por isso nunca fará a primeira substituição.
Riley

@seshoumara echo -n | sed 's:a\?:&a:g'e não obteve saída. Seria o mesmo sed 's::a:'que não corresponderia a nada.
Riley

Com echo -nabsolutamente nada é passado para o sed, mas o sed não pode ser iniciado sem a entrada do projeto. Verifique este meta link para ver se echo|sedé a maneira aceita de iniciar o sed para desafios que invocam uma regra de não entrada.
seshoumara

@seshoumara Eu pensei que ainda daria uma string vazia. Isso parece funcionar então. Obrigado!
Riley

9

R, 22 25 22 20 18 bytes

Edit: Obrigado a @Mego por apontar que R não suporta otimização de chamada de cauda.

Edit4: Encontrou uma solução ainda mais curta que simples, mas bastante intrincada.

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

A resposta usa a variável de verdade booleana incorporada, Tque é diminuída indefinidamente no loop de repetição. A função ls()é chamada cada iteração que lista todos os objetos no ambiente atual. No entanto, o primeiro argumento nameespecifica de qual ambiente a partir do qual listar objetos. A partir da documentação R, descobrimos que:

O argumento name pode especificar o ambiente a partir do qual os nomes dos objetos são obtidos em uma das várias formas: como um número inteiro (a posição na searchlista); como o nome da sequência de caracteres de um elemento na lista de pesquisa; ou como explícito environment(incluindo o uso sys.framepara acessar as chamadas de função ativas no momento).

Isso significa principalmente que, na primeira iteração, executamos o ls(-1)que retornaria character(0)(padrão ao tentar acessar o everything-except-the-firstelemento inexistente de qualquer objeto do tipo caractere). Durante a segunda iteração, Té decrementado por dois e, posteriormente, chamamos ls(-3)que, por sua vez, retorna o erro:

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

Isso ocorre porque tentamos listar o everything-except-the-thirdelemento, mas o ambiente local contém apenas a variável Tneste momento (como tal, ls()retornaria uma lista de comprimento 1nessa iteração) e um erro é retornado.


11
Isso não parece que a recursão seja feita com a otimização da chamada de cauda, ​​se houver um limite de recursão.
Mego

@Mego Depois de algumas investigações, descobri que o R realmente não suporta a otimização da chamada de cauda, ​​então essa resposta não é válida (nunca ouvi falar do conceito antes). Mudará para uma resposta válida em um momento.
Billywob

9

Befunge-93, 3 bytes (possivelmente 1 ou 0)

!%!

Experimente online!

Na primeira iteração do loop, a pilha está vazia, o que equivale a todos os zeros. A !operação (not) converte a parte superior da pilha em 1, e a %operação (módulo) calcula 0 mod 1, deixando 0. A !operação seguinte converte esse 0 em 1 antes que o contador do programa se envolva e inicie o loop novamente.

Na segunda iteração, as primeiras !operações convertem o 1 que está agora no topo da pilha em um 0. A %operação calcula 0 mod 0, que produz uma divisão por erro zero no interpretador de referência e, assim, finaliza o programa.

Há também a resposta mais chata de 1 byte, embora não tenha certeza se isso é considerado válido.

"

Experimente online!

Esse "comando inicia uma sequência, portanto, todo espaço no restante da linha é empurrado para a pilha até que o contador do programa se envolva e encontre o "fechamento da sequência novamente. Em seguida, será necessário agrupar uma segunda vez para repetir o processo iniciando outra sequência e empurrando outros 79 espaços para a pilha. Eventualmente, isso ficará sem memória (o comportamento do interpretador de referência) ou produzirá um estouro de pilha.

Agora, se você realmente deseja seguir as regras, também existe tecnicamente uma solução de zero byte.


Se você tomar esta decisão como significando que qualquer intérprete define o idioma (como muitos fazem aqui), podemos assumir por um momento que o idioma Befunge é definido por esse intérprete . E um dos "recursos" desse intérprete é que ele coloca um valor Indefinido na pilha para cada loop do campo de jogo ao executar um programa em branco. Com tempo suficiente, a memória acabará eventualmente.

A rapidez com que isso depende dependerá da velocidade do computador, da memória disponível e do navegador sendo usado. Na minha máquina, descobri que o Microsoft Edge funcionava melhor, mas mesmo assim era "apenas" usando 500 MB após dois minutos. Foi só por volta dos quinze minutos (com vários gigabytes usados) que o Edge decidiu interromper o processo e atualizar a guia. Portanto, é improvável que chegue ao prazo de dois minutos, mas com as condições corretas que não estariam necessariamente fora de questão.


8

FALSO, 8 bytes

Eu realmente gosto dessa linguagem.

1[$][.]#

Isso pressiona a e 1, em seguida, faz um [$][.]#loop enquanto $true (parte superior duplicada da pilha) e ( .) a produz. Esse intérprete falha após a 1impressão do single (evidência de que o loop está sendo executado pelo menos uma vez.) Parece haver um erro nesse intérprete. O seguinte programa de 9 bytes deve funcionar em todos os intérpretes compatíveis:

1[$][..]#

Você também deve tentar o DUP, que é basicamente um superconjunto de FALSE. Isso é o que eu costumava fazer RETURN.
Mama Fun Roll

@MamaFunRoll oh sim, eu esqueci que você fez RETURN! Eu tenho que tentar esse. : D
Conor O'Brien

@MamaFunRoll Eu amo o DUP, acabei de escrever um intérprete do DUP e estou brincando com ele.
ML

@ ConnorO'Brien: Eu diria que sua primeira solução deve travar qualquer intérprete. Acabei de executar uma depuração com meu próprio intérprete, e é óbvio que o primeiro .esvazia a pilha de dados, enquanto no segundo loop $tenta duplicar o elemento superior da pilha vazia, o que deve levar a um erro (bem, meu intérprete ) A segunda versão não deve ser válida porque nem sequer termina o primeiro loop, porque já tenta acessar a pilha vazia prematuramente.
ML

Para o seu segundo exemplo, aqui está um Dump de depuração colorido do meu interpretador DUP. fica óbvio depois que você vê como a pilha de dados (ds) e a pilha de retorno (rs) funcionam, a última não sendo transparente em FALSE.
ML

8

C, 21 bytes

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

Aqui ié garantido para começar como 0.

Pode-se confirmar que isso é executado da seguinte maneira:

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

Que, na minha máquina, resulta em:

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

A solução recursiva mais curta que encontro é de 22 bytes :

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

gccsomente a eliminação da chamada de cauda é igual -O2ou superior, momento em que precisamos chamar uma função como putspara impedir que tudo seja otimizado. Confirmação de que isso 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

A seguir, é apresentado um programa completo, que assume que é chamado sem argumentos de linha de comando, em 22 bytes :

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

que é equivalente à função do mesmo comprimento:

f(i){for(i=1;1/i--;);}

Uma função como essa é tratada como principal? Se for, o primeiro argumento é o comprimento da lista de argumentos (que é 1, o nome que foi usado para chamá-lo).
Riley #

Ou, o registrador de argumento ainda tem o valor que estava lá da principal sendo chamado.
Riley #

@Riley Ahh, a última teoria parece ser o caso, como evidenciado pelo fato de que o número aumenta à medida que argumentos de linha de comando são adicionados. Obrigado pela compreensão!
Maçaneta

Eu não tinha certeza de como você estava chamando isso no meu primeiro palpite, mas eu deveria ser o mesmo que o primeiro argumento da função que chama f.
Riley #

Sim, tio
Riley

6

MATLAB, 18 bytes

Isso pode ser executado como um script:

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

A primeira iteração é boa, pois j(1)é justa 1. A segunda iteração trava com um erro de matriz fora dos limites, pois j(2)excede as dimensões de j, que é uma matriz 1x1.

Isso também pode ser executado como um script, mas funciona apenas na primeira vez em que você o executa. Ainda assim, é um abuso bastante hilário das constantes predefinidas do MATLAB que eu pensei em incluí-lo. Também tem 18 bytes.

while i/i;i={};end

Quando executada em um espaço de trabalho em que a variável iainda não foi definida, assume-se que ié a unidade imaginária i/i = 1. No primeiro loop, a atribuição i={}cria uma matriz de células vazia chamada i. Na segunda iteração, o loop sai com "Operador indefinido '/' para argumentos de entrada do tipo 'célula'".


Ambos são incríveis! Você provavelmente sabe disso, mas j(2)normalmente dar uma matriz de 2-por-2 com0+1i
Stewie Griffin

Obrigado! Isso é verdade em Octave, mas não no MATLAB Eu acho
MattWH

6

Perl 6 , 13 bytes

loop {5[$++]}

Indexa um literal inteiro em um loop infinito.
Confia no fato de que, em valores escalares, a sintaxe de indexação da matriz pode ser usada com o índice 0(retornando o próprio valor), mas gera um Index out of rangeerro para qualquer outro índice.


6

QBasic, 17 bytes

Este código é muito estranho.

DO
i=11+a(i)
LOOP

Como funciona

No QBasic, as variáveis ​​são pré-inicializadas. Uma variável regular sem nenhum sufixo de tipo, como iaqui, é pré-inicializada para zero.

Exceto se você tentar se inscrever nessa variável como uma matriz ... nesse caso, é uma matriz de 11 zeros. *

Na primeira vez no loop, portanto, ié 0e aé uma matriz. a(i)fornece o elemento zeroth da matriz (que é 0). Tudo bem e bem. Montamos ia 11e loop. Mas agora 11não é um índice válido para a matriz ae o programa pára com Subscript out of range.

Uma versão de 19 bytes que mostra melhor o que está acontecendo:

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

Isso será impresso 0onze vezes antes de ocorrer um erro.


* Conceitualmente, é uma matriz de 10 elementos. A maioria das coisas no QBasic são indexadas 1, mas as matrizes não são, possivelmente por motivos de implementação. Para fazer as coisas funcionarem conforme o esperado para programadores, o QBasic lança uma entrada extra para que você possa usar os índices 1 a 10. O índice 0, no entanto, ainda é perfeitamente acessível. Vai saber.


QBasic e matrizes, onde a diversão pára!
steenbergh

Como o erro não precisa estar no segundo loop, você não poderia i=1+a(i)?
Quelklef

@Quelklef Não, você teria que fazer i=i+1+a(i). Caso contrário, o índice nunca ficará acima 1, o que não é um erro.
DLosc 24/12/16

@DLosc Oh, você está certo.
Quelklef

5

Haskell, 15 bytes

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

f"a"executa de forma recursiva a sequência "a", eliminando o primeiro caractere e, eventualmente, falha ao final com uma Non-exhaustive patterns in function fexceção, porque fé definida apenas para sequências não vazias.


5

C #, 71 38 bytes

Como você forneceu um exemplo em C #, aqui outra versão jogou golfe

E graças a pinkfloydx33

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

Mais curto do Parse.ToString()que Parse($"{c--}") eu e até mesmo o que eu deixei mentalmente checkedpor ser uma palavra-chave muito longa. Difícil, certamente é mais curto do queParse(c.ToString())

Resposta original

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

Isto irá iniciar c=0, em seguida, diminui-lo, quando c=-1o uint.Parsefará com um:

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

Versão não gasta e verificação desse loop é executado pelo menos uma vez

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

for(int c=0;;)uint.Parse($"{c--}");
usar o seguinte

11
checked{for(uint c=1;;)c--;}
precisa

Ok, uau! Não sabia sobre a taquigrafia '$'!
MrPaulch

4

CJam , 4 bytes

1{}g

Experimente online!

A primeira iteração do {}gloop vazio aparece o 1, o que diz para continuar. A segunda iteração tenta exibir outra condicional, mas a pilha está vazia, então o programa trava.


4

assembly x86 (sintaxe da AT&T), 40 bytes

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

Declara uma função f que divide 1 por 1 em sua primeira iteração e tenta dividir 0 por 0 e erros.


Você pode salvar 4 bytes por comutação de sintaxe Intel :)
mriklojn

6
Normalmente, pontuamos a montagem pelo tamanho do código de bytes gerado, não pelas instruções legíveis por humanos.
Dennis

O conjunto montado @Dennis é uma linguagem de máquina. mas sim, isso pode ser reivindicado muito mais curto na forma de linguagem de máquina.
Jasen

Livre-se do rótulo f e do mov. Troque o dec e div, e você pode se livrar ainda mais.
Clearer

4

CJam, 4 bytes

P`:~

P`gera a string 3.141592653589793. :~avalia cada personagem. 3é um código válido no CJam que simplesmente retorna 3. Na próxima iteração, .causa um erro porque requer um dígito ou um operador para segui-lo.




4

Lote, 22 20 bytes

:a
set i=%i%1
goto a

Explicação

Este é um loop infinito que acrescenta um 1a uma string inicialmente vazia. Eventualmente, isso passará o comprimento máximo da string de 8192 e falhará. Na minha máquina, isso leva cerca de 30 segundos.


Agradável! Você pode salvar 2 bytes usando as terminações de linha do Unix.
Briantist

Você pode usar% 0, que é o nome do arquivo, em vez do rótulo e ir para.
YourDeathIsComing

Eu não tinha certeza se isso quebrou a regra da recursão da cauda.
SomethingDark

4

JavaScript, 9 bytes

for(;;i);

Isso é executado uma vez e depois lança o ReferenceError: i is not definedque interrompe o loop.

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


Tomando o seguinte como exemplo, é o <increment>fim do primeiro ciclo ou o início do segundo ciclo?

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

1 / eu vejo

Depois de passar das linhas 0 à linha 3 e depois voltar à linha 0, parece que um ciclo completo foi concluído.
Isso daria <increment>início ao segundo ciclo.
- Primeiro ciclo: <init>-> <test>-> <statement>
- Segundo ciclo: <increment>-> <test>-><statement>

2 / Whileequivalente

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

Neste equivalente whilea <increment>é o fim do primeiro ciclo e parece que é o mesmo com o for.
Isso faria <increment>o fim do primeiro ciclo.
- Primeiro ciclo: <test>-> <statement>-> <increment>
- Segundo ciclo: <test>-> <statement>-><increment>

3 / Uma declaração é encontrada duas vezes

Um ciclo completo é concluído quando uma instrução é encontrada duas vezes.
A primeira declaração encontrada duas vezes é <test>.
Isso faria <increment>o fim do primeiro ciclo.
- Primeiro ciclo: <test>-> <statement>-> <increment>
- Segundo ciclo: <test>-> <statement>-><increment>

4 / É uma configuração

O <init>é apenas a criação de tudo o que é necessário para o primeiro ciclo.
O <increment>é apenas a criação de tudo o que é necessário para o segundo ciclo.
Isso daria <increment>início ao segundo ciclo.
- Primeiro ciclo: <init as a setup>-> <test>-> <statement>
- Segundo ciclo: <increment as a setup>-> <test>-><statement>


A especificação de idioma do ECMAScript® 2016

Tempo de execução de for(<init>;<test>;<increment>)<statement>;

Seja varDcl o resultado da avaliação <init>.
ReturnIfAbrupt (varDcl).
Retorna ? ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelSet).

Existem três formas, então eu peguei a mais curta aqui, não há diferença:
- Seja <init>qual for, não faz parte da primeira iteração.
- O que é relevante está em ForBodyEvaluation.

Detalhes de ForBodyEvaluation ( <test>, <increment>, <statement>, «», labelSet)

0 Seja V indefinido.
1 Executar? CreatePerIterationEnvironment (perIterationBindings).
2 Repita
3 Se não estiver [vazio],
4 Seja testRef o resultado da avaliação <test>.
5 Seja testValue? GetValue (testRef).
6 Se ToBoolean (testValue) for falso, retorne NormalCompletion (V).
7 Deixe que o resultado seja o resultado da avaliação <statement>.
8 Se LoopContinues (resultado, labelSet) for falso, retorne Conclusão (UpdateEmpty (resultado, V)).
9 Se o resultado [[Valor]] não estiver vazio, seja V o resultado. [[Valor]].
10 Executar? CreatePerIterationEnvironment (perIterationBindings).
11 Se não estiver [vazio], então
12 Seja incRef o resultado da avaliação <increment>.
13 Executar? GetValue (incRef).

6 / eu vejo

Um ciclo completo, uma execução completa da parte de repetição.
Isso faria <increment>o fim do primeiro ciclo.
- Primeiro ciclo: <test>-> <statement>-> <increment>/ Em outras palavras, da linha 3 à linha 13
- Segundo ciclo: <test>-> <statement>-> <increment>/ Em outras palavras, da linha 3 à linha 13

7 / Um ciclo é uma iteração

Um ciclo começa com CreatePerIterationEnvironment.
Então, quando CreatePerIterationEnvironmenté encontrado, um novo ciclo começa, terminando assim o anterior.
Isso daria <increment>início ao segundo ciclo.
- Primeiro ciclo: <test>-> <statement>/ Em outras palavras, da linha 1 à linha 9
- Segundo ciclo: <increment>-> <test>-> <statement>/ Em outras palavras, da linha 10 em loop até a linha 9


É o <increment>fim do primeiro ciclo ou o início do segundo ciclo?

A explicação correta é 6 ou 7.


8
Acho que estou mais inclinado a atribuir o incremento ao final da primeira iteração, em vez de ao início da segunda iteração ou a nenhuma iteração. Suponho que essa seja uma ambiguidade da questão.

11
Como for(a;b;c)d;é aproximadamente equivalente a a;while(b){d;c;}, estou inclinado a dizer que o erro ainda é gerado na primeira iteração (antes que a condição do loop seja verificada pela segunda vez).
ETHproductions

@Hurkyl A primeira iteração começa com a inicialização, então eu acho que o incremento deve ser o início da segunda iteração.
Hedi

4
Se você ler a especificação , poderá ver que a operação de incremento é a última parte da iteração e, como tal, ainda pertence à primeira iteração.
Nit

3
@ Hedi Não vejo como isso é relevante. A operação de incremento é claramente uma parte da primeira execução do loop. Para reformular, quando a operação de incremento é chamada, o loop não concluiu uma única execução completa.
Nit

4

INTERCAL , 12 bytes

(1)DO(1)NEXT

Experimente online!

NEXTé o principal comando de fluxo de controle do INTERCAL-72. (Revisões posteriores introduzidas COME FROM, que ficaram mais famosas, mas não estavam na versão original da linguagem; e todas as implementações INTERCAL concluídas estou ciente do suporte NEXTà compatibilidade com versões anteriores, com todos, exceto um, habilitando o suporte por padrão. Não sinto a necessidade de nomear INTERCAL-72 especificamente no título.)

Ao usar NEXTpara formar um loop, você deve usar RESUMEou FORGETpara liberar o espaço que ele usa para lembrar onde o programa esteve; RESUMEretroativamente transforma o NEXTalgo em algo semelhante a uma chamada de função (embora você possa retornar de funções diferentes daquela em que está), enquanto o FORGETtransforma em algo mais semelhante a uma instrução GOTO. Se você não o fizer (e este programa não), o programa falhará após 80 iterações (esse comportamento é realmente especificado na especificação INTERCAL).

É um tanto ambíguo se isso conta como recursão ilimitada (não permitido na pergunta); você certamente pode usar esse tipo de NEXTpara implementar uma chamada de função; nesse caso, seria efetivamente uma função recursiva, mas não há informações suficientes aqui para determinar se estamos fazendo uma chamada de função ou não. Pelo menos, eu estou postando isso de qualquer maneira, porque não viola as regras de maneira inequívoca, e uma implementação INTERCAL que otimizava a "chamada final" não apenas violava a especificação, mas também fazia com que a maioria dos programas existentes falhasse, porque retornando de a "função incorreta" é a principal maneira de fazer o equivalente a uma instrução SE.

Aqui está a mensagem de erro resultante, conforme gerada pelo C-INTERCAL:

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

(Observe que a segunda linha é recuada com uma tabulação e a terceira com oito espaços. Isso parece correto em um terminal ou em praticamente qualquer programa que tenha tabulação em múltiplos de 8. No entanto, o Markdown tem tabulação em múltiplos de quatro, violando as suposições que a maioria dos programas mais antigos faz sobre guias, por isso a mensagem de erro é um pouco malformada aqui.)


O erro realmente diz CORRECT SOURCE AND RESUBNIT? Como em um erro de digitação na mensagem de erro C-INTERCAL original?
Andrakis 25/12/16

11
@ Andrakis: Sim, ele faz. Esse erro de digitação foi cuidadosamente preservado por anos.

3

Pitão, 3 bytes

W1w

Experimente online.

W1está apenas while 1:em Python. O corpo do loop imprime uma linha lida em STDIN, que trava na segunda iteração quando o código é executado com entrada vazia.

Se os loops usando #(loop até erro) forem banidos (suponho que sim), acho que esse é o menor tempo possível.


3

Python 3, 29 bytes

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

Realmente simples. Na segunda chamada para x, eu não estou lá, e o Python reclama.


3

Labirinto , 3 bytes

#(/

Experimente online!

Como a maioria das linguagens 2D, o Labyrinth não possui nenhuma construção de loop explícita. Em vez disso, qualquer código que seja disposto de maneira que seja executado várias vezes seguidas é um loop nesses idiomas. Para o caso do labirinto, um programa linear simples atua como um loop, porque o ponteiro da instrução irá saltar para frente e para trás. Se o programa for abc(para alguns comandos a, be c), em seguida, a execução real será abcbabcbabcb...para ser executado abcbem um loop infinito.

Quanto ao motivo pelo qual esse programa específico falha na segunda iteração desse loop, eis o que os comandos individuais fazem. Observe que a pilha do labirinto contém uma quantidade infinita implícita de zeros na 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.

3

Bash, 11 (Borderline não concorrente)

exec $0 1$@

Esse script se executa recursivamente, acrescentando 1aos argumentos passados ​​em cada iteração. Eu acho que isso conta como TCO, porque o executivo reutiliza o espaço do processo, mas não consome a pilha. É limítrofe não concorrente porque levou cerca de 10 minutos antes de ser morto na minha máquina - YMMV.


11
exec $0 1$@$@ termina muito mais rápido, mas tem dois caracteres a mais.
Jasen

3

cmd, 34 bytes

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

Isso mudará %ide 0 a 10. O colorcomando (antigo) aceitará com prazer qualquer argumento que tenha 2 (hexa-) dígitos decimais. Com o argumento, 100ele falhará, imprimindo a mensagem de ajuda e configurando ERRORLEVELpara 1.

Prova do loop sendo executada pelo menos uma vez: a cor do seu shell será diferente!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.