Aviso : Esses programas são bombas clone (uma espécie de forma menos perigosa, mas ainda perigosa, de uma bomba bifurcada); como tal, não os execute em um sistema de produção sem sandboxing ou limites de recursos . As bombas clonadas criam threads em um loop (ao contrário das bombas de garfo, que criam processos em um loop), assim você pode detê-las simplesmente matando o processo em questão (tornando-as muito menos perigosas que as bombas de garfo, o que pode ser muito difícil de limpar); mas eles provavelmente amarrarão a maior parte de sua CPU até que você consiga fazê-lo (ou até o programa vencer e sair naturalmente por si só). Solicitar que o seu sistema operacional coloque limites à quantidade de memória e tempo de CPU que esses programas podem usar deve criar um ambiente seguro para testá-los.
Java (OpenJDK 8) , 65 60 bytes (com uma pequena modificação no wrapper)
Thread x=Thread.currentThread();new Thread(x::stop).start();
Experimente online!
Requer que ambas as instâncias de catch (Exception …)
na pergunta sejam alteradas para catch (Throwable …)
. Em teoria, isso deveria ser mais seguro, não menos, mas permite que essa solução seja possível.
Salvei 5 bytes sobre a primeira versão desta resposta usando uma referência de método em vez de uma lambda.
Java 4, 104 bytes (não testado, deve funcionar com o wrapper original)
final Thread x=Thread.currentThread();new Thread(){public void run(){x.stop(new Exception());}}.start();
Experimente online! (o link vai para uma implementação do Java 8, portanto, não funciona)
Usando recursos que foram removidos das versões modernas do Java, é possível resolver até a versão do quebra-cabeça que requer um Exception
. Provavelmente, pelo menos. (O Java 4 já é muito antigo e não me lembro quais recursos ele contém ou não. Como pode ser visto, havia muito menos recursos no Java naquela época e, portanto, era mais detalhado; não tínhamos lambdas, então eu tive que criar uma classe interna.)
Explicações
A maioria das soluções para esta pergunta está em C # (junto com uma solução Java que engana usando colchetes desbalanceados como uma forma de injeção de código e uma solução Perl que também não está em Java). Então pensei que valeria a pena tentar mostrar como esse quebra-cabeça também pode ser resolvido "adequadamente" em Java.
Ambos os programas são efetivamente idênticos (portanto, o fato de o primeiro programa funcionar me dá grande confiança de que o segundo programa também funcionaria, a menos que eu tenha acidentalmente usado um recurso que não seja Java-4; Thread#stop
foi preterido no Java 5).
O Thread#stop
método de Java funciona, nos bastidores, fazendo com que um lançamento seja lançado no encadeamento em questão. O lançamento planejado para esse fim é ThreadDeath
( Error
especificamente, porque as pessoas geralmente tentam capturar exceções e os designers de Java não queriam que isso acontecesse), embora isso permita que você jogue qualquer coisa (ou acostume-se; em algum momento após o término da API) projetados, os designers de Java perceberam que essa era uma idéia incrivelmente ruim e removeram a versão do método que leva os argumentos diretamente). Obviamente, mesmo a versão lançada ThreadDeath
é uma operação bastante arriscada sobre a qual você pode dar poucas garantias (por exemplo, permite solucionar esse quebra-cabeça, algo que "não deveria" ser possível), então você não deve use-o, mas a partir do Java 8, ele ainda funciona.
Esse programa funciona gerando um novo encadeamento e solicitando que ele force uma exceção de volta ao encadeamento principal. Se tivermos sorte, isso será feito em um momento em que estamos fora do catch
bloco interno (não podemos escapar do catch
bloco externo até que o programa termine, porque há um loop em torno dele). Como já adicionamos o loop de maneira conveniente, é economizador de bytes simplesmente usá-lo para permitir a criação de threads, na esperança de que um deles atinja o tempo correto. Isso normalmente parece acontecer em alguns segundos.
(Nota do TIO: a versão atual do TIO está bastante inclinada a interromper esse programa no início de sua execução, provavelmente devido a todos os threads que estão sendo criados. Ele pode funcionar no TIO, mas não funciona de maneira confiável, portanto, muitas vezes são necessárias algumas tentativas para obtenha a saída "Você ganhou!".)