Avvertenza : questi programmi sono bombe a clone (una sorta di bomba a forcella meno pericolosa ma ancora pericolosa); come tale, non eseguirli su un sistema di produzione senza sandbox o limiti di risorse . Le bombe clonate creano fili in un ciclo (al contrario delle bombe a forcella, che creano processi in un ciclo), quindi puoi fermarli semplicemente uccidendo il processo in questione (rendendoli molto meno pericolosi delle bombe a forcella, che può essere molto difficile da mettere in ordine); ma probabilmente collegheranno la maggior parte della tua CPU fino a quando non riuscirai a farlo (o fino a quando il programma vincerà e uscirà naturalmente da solo). Chiedere al sistema operativo di porre limiti alla quantità di memoria e al tempo di CPU che questi programmi sono autorizzati a utilizzare dovrebbe creare un ambiente sicuro in cui testarli.
Java (OpenJDK 8) , 65 60 byte (con una leggera modifica al wrapper)
Thread x=Thread.currentThread();new Thread(x::stop).start();
Provalo online!
Richiede la modifica di entrambe le istanze di catch (Exception …)
nella domanda catch (Throwable …)
. Questo dovrebbe in teoria essere più sicuro, non meno, ma consente a questa soluzione di essere possibile.
Ho salvato 5 byte sulla prima versione di questa risposta usando un riferimento al metodo anziché un lambda.
Java 4, 104 byte (non testato, dovrebbe funzionare con il wrapper originale)
final Thread x=Thread.currentThread();new Thread(){public void run(){x.stop(new Exception());}}.start();
Provalo online! (il collegamento va a un'implementazione Java 8, quindi non funzionerà)
Utilizzando le funzionalità che sono state rimosse dalle versioni moderne di Java, è possibile risolvere anche la versione del puzzle che richiede un Exception
. Probabilmente, almeno. (Java 4 è ormai molto vecchio e non riesco a ricordare quali funzioni avesse e non contenesse. Come si può vedere, allora c'erano molte meno funzioni in Java ed era quindi più prolisso; non avevamo lambdas, quindi ho dovuto creare una classe interiore.)
spiegazioni
La maggior parte delle soluzioni a questa domanda sono in C # (insieme a una soluzione Java che imbroglia usando le parentesi sbilanciate come una forma di iniezione di codice e una soluzione Perl che non è anche in Java). Quindi ho pensato che valesse la pena provare a mostrare come questo puzzle possa essere risolto "correttamente" anche in Java.
Entrambi i programmi sono effettivamente identici (quindi il fatto che il primo programma funzioni mi dà la sicurezza che anche il secondo programma funzionerebbe, a meno che non abbia accidentalmente usato una funzione non Java-4; è Thread#stop
stato deprecato in Java 5).
Il Thread#stop
metodo Java funziona, dietro le quinte, tramite il lancio di un lancio nel thread in questione. Il lancio previsto per lo scopo è ThreadDeath
(un Error
, in particolare perché le persone spesso cercano di catturare eccezioni e i progettisti di Java non volevano che ciò accadesse), anche se ti consente di lanciare qualsiasi cosa (o l'abitudine a; a un certo punto dopo che l'API era progettato, i progettisti di Java hanno capito che si trattava di una pessima idea e hanno rimosso la versione del metodo che prende apertamente gli argomenti). Naturalmente, anche la versione che genera ThreadDeath
è un'operazione abbastanza rischiosa di cui puoi fare poche garanzie (ad esempio, ti consente di risolvere questo puzzle, qualcosa che "non dovrebbe" essere possibile), quindi non dovresti usalo, ma a partire da Java 8, funziona ancora.
Questo programma funziona generando un nuovo thread e chiedendogli di restituire forzatamente un'eccezione nel thread principale. Se siamo fortunati, lo farà in un momento in cui siamo fuori dal catch
blocco interno (non possiamo sfuggire al catch
blocco esterno fino a quando il programma non termina, perché c'è un ciclo attorno ad esso). Poiché abbiamo già aggiunto il loop convenientemente, è un risparmio di byte utilizzare semplicemente quel loop per consentirci di continuare a creare thread, nella speranza che uno di essi alla fine raggiunga il tempismo corretto. Questo sembra accadere normalmente entro un paio di secondi.
(Nota TIO: l'attuale versione di TIO è abbastanza incline a uccidere questo programma all'inizio della sua esecuzione, presumibilmente a causa della creazione di tutti i thread. Può funzionare su TIO, ma non funziona in modo affidabile, quindi spesso sono necessari alcuni tentativi per ottieni l'output "Hai vinto!".)