Попередження : ці програми - це клонові бомби (така собі менш небезпечна, але все-таки небезпечна форма вилкової бомби); як такий, не запускайте їх у виробничій системі без пісочниць або обмежень ресурсів . Клоновані бомби створюють нитки в циклі (на відміну від вилкових бомб, які створюють процеси в циклі), таким чином ви можете зупинити їх, просто вбиваючи процес, про який йде мова (роблячи їх набагато менш небезпечними, ніж вилкові бомби, що може бути дуже важко очистити); але вони, швидше за все, пов'язатимуть більшу частину вашого процесора, поки вам не вдасться це зробити (або поки програма не виграє і не вийде природним шляхом сама по собі). Попросивши вашу ОС встановити обмеження на об'єм пам'яті та час процесора, якими ці програми можуть використовуватись, слід створити безпечне середовище, в якому їх можна перевірити.
Java (OpenJDK 8) , 65 60 байт (з незначною зміною обгортки)
Thread x=Thread.currentThread();new Thread(x::stop).start();
Спробуйте в Інтернеті!
Потрібно catch (Exception …)
змінити обидва екземпляри запитання catch (Throwable …)
. Теоретично цього повинно бути більше безпечним, а не меншим, але це дозволяє зробити це рішення можливим.
Я врятував 5 байт на першій версії цієї відповіді за допомогою посилання на метод, а не лямбда.
Java 4, 104 байти (не перевірено, має працювати з оригінальною обгорткою)
final Thread x=Thread.currentThread();new Thread(){public void run(){x.stop(new Exception());}}.start();
Спробуйте в Інтернеті! (посилання йде на реалізацію Java 8, тому не працюватиме)
Використовуючи функції, вилучені з сучасних версій Java, можна вирішити навіть версію головоломки, яка вимагає Exception
. Напевно, принаймні. (Java 4 на сьогоднішній день дуже стара, і я не можу згадати, які функції в ній були, а не містилися. Як видно, у Java тоді було набагато менше функцій, і тому вона була більш багатослівною; у нас не було лямбда, тому мені довелося створити внутрішній клас.)
Пояснення
Більшість рішень цього питання знаходяться в C # (разом із рішенням Java, яке обманює використання неврівноважених дужок як форми введення коду, і рішення Perl, яке також відсутнє на Java). Тому я подумав, що варто спробувати показати, як ця головоломка може бути розв'язана "належним чином" і в Java.
Обидві програми фактично однакові (таким чином, той факт, що перша програма працює, дає мені високу впевненість, що друга програма теж буде працювати, якщо тільки я випадково не використовував функцію, яка не є Java-4; Thread#stop
була заборонена в Java 5).
Thread#stop
Метод Java працює поза кадром, через те, що кидається в нитку, про яку йдеться. Цільова мета, яка призначена для цієї мети ThreadDeath
(а Error
саме тому, що люди часто намагаються виганяти винятки, і дизайнери Java не хотіли, щоб це сталося), хоча це дозволяє кидати що-небудь (або звик; у якийсь момент після того, як API був розроблені дизайнерами Java зрозуміли, що це неймовірно погана ідея, і видалили версію методу, яка виводить аргументи прямо). Звичайно, навіть версія, яка кидає, ThreadDeath
- це досить ризикована операція, щодо якої ви можете дати кілька гарантій (наприклад, вона дозволяє вирішити цю головоломку, те, що "не повинно" бути можливим), тому вам не слід використовуйте його, але як у Java 8, він все ще працює.
Ця програма працює за допомогою нерестування нової нитки та прохання її насильно перекинути виняток у основний потік. Якщо нам пощастить, це зробиться в той момент, коли ми знаходимось поза внутрішнім catch
блоком (ми не можемо уникнути зовнішнього catch
блоку, поки програма не закінчиться, оскільки навколо нього є петля). Оскільки у нас вже зручно додано цикл, це економія байтів просто використовувати цю петлю, щоб ми могли продовжувати створювати нитки, сподіваючись, що одна з них врешті-решт потрапить у правильний час. Здається, це зазвичай відбувається через пару секунд.
(Примітка TIO: поточна версія TIO досить схильна знищити цю програму на початку її виконання, імовірно, завдяки всім створеним потокам. Вона може працювати на TIO, але не працює надійно, тому часто потрібно кілька спроб отримати вихід "Ви виграли!".)