Это ограничено Java и C # синтаксисом, который я предполагаю.
В этой задаче программирования вы должны производить Exception
s, которые могут быть перехвачены, но снова выброшены в конце блока catch.
try
{
while(true)
try
{
// you are only allowed to modify code between this try { } brackets
}
catch(Exception ex2) { }
}
catch(Exception ex1)
{
// your goal is to reach this catch block by modifying the code ...
// in the inner try block above
// You win if you reach this part and execute on of the following code lines
Console.WriteLine("You won!"); // for C#
// Or
System.out.println("You won!"); // for Java
}
Вы можете свободно размещать код до и после этого фрагмента.
Самый короткий код для достижения внешнего catch
блока выигрывает.
code-golf
c#
java
programming-puzzle
user21634
источник
источник
Ответы:
C #, 46 (88, включая шаблон)
Abort()
Метод вызывает ThreadAbortException , который представляет собой специальное исключение, которое автоматически вызван повторно в конце каждого блока улова (еслиThread.ResetAbort()
не называется).источник
C # 24 символов
завершает внутренний блок try раньше запланированного, что позволяет мне вызвать исключение за пределами блока try.
источник
int a=1/0;
?)int a=
там нужно ? Некоторые языки позволяют просто написать выражение1/0
Ява, 76 или 31
Считать только вставки, сделанные в код, игнорируя новые строки. 76, если вы посчитаете все, что я добавил, 31, если вы исключите первую и последнюю строки, т.е. только подсчет
int a=1/0;try{}catch(Error e){}
.источник
catch
блок после фрагмента, он не сделал.Java (OpenJDK 8) ,
6560 байт (с небольшой модификацией оболочки)Попробуйте онлайн!
Требует, чтобы оба экземпляра
catch (Exception …)
в вопросе были изменены наcatch (Throwable …)
. Теоретически это должно быть более безопасным, а не менее, но оно позволяет сделать это решение возможным.Я сохранил 5 байтов поверх первой версии этого ответа, используя ссылку на метод, а не лямбду.
Java 4, 104 байта (не проверено, должно работать с оригинальной оболочкой)
Попробуйте онлайн! (ссылка идет на реализацию Java 8, поэтому не будет работать)
Используя функции, которые были удалены из современных версий Java, можно решить даже ту версию головоломки, которая требует
Exception
. Возможно, по крайней мере. (Java 4 сейчас очень старая, и я не могу вспомнить, какие функции она имела и не содержала. Как можно видеть, тогда в Java было намного меньше функций, и поэтому она была более многословной; у нас не было лямбды, поэтому мне пришлось создать внутренний класс.)Пояснения
Большинство решений этого вопроса находятся на C # (вместе с решением Java, которое обманывает, используя несбалансированные скобки в качестве формы внедрения кода, и решением Perl, которое также отсутствует в Java). Поэтому я подумал, что стоит попытаться показать, как эта головоломка может быть решена «правильно» и в Java.
Обе программы фактически идентичны (поэтому тот факт, что первая программа работает, дает мне высокую уверенность в том, что вторая программа тоже будет работать, если только я случайно не использовал функцию, отличную от Java-4;
Thread#stop
в Java 5 она устарела).Thread#stop
Метод Java работает за кулисами, заставляя бросаемый объект бросаться в рассматриваемый поток. Функция throwable предназначена для этой целиThreadDeath
(вError
частности, потому что люди часто пытаются скрыть исключения, а разработчики Java не хотят, чтобы это происходило), хотя она позволяет вам что-либо генерировать (или раньше) в некоторый момент после того, как API был Разработчики Java поняли, что это невероятно плохая идея, и удалили версию метода, в которой аргументы принимаются прямо). Конечно, даже версия, которую выкидывает,ThreadDeath
является довольно рискованной операцией, в отношении которой вы можете дать несколько гарантий (например, она позволяет решить эту головоломку, что-то, что «не должно быть» возможно), поэтому вы не должны используйте его, но на Java 8 он все еще работает.Эта программа работает, порождая новый поток и заставляя его принудительно выбросить исключение обратно в основной поток. Если нам повезет, он сделает это в тот момент, когда мы находимся вне внутреннего
catch
блока (мы не можем выйти из внешнегоcatch
блока, пока программа не завершится, потому что вокруг него есть цикл). Поскольку у нас уже удобно добавлен цикл, экономия байтов состоит в том, чтобы просто использовать этот цикл, чтобы позволить нам продолжать создавать потоки в надежде, что один из них в конечном итоге достигнет правильного времени. Обычно это происходит в течение нескольких секунд.(Примечание TIO: текущая версия TIO довольно склонна убивать эту программу на ранних этапах ее выполнения, вероятно, из-за всех создаваемых потоков. Она может работать на TIO, но не работает надежно, поэтому часто требуется несколько попыток получите вывод «Вы выиграли!».)
источник
C #
источник
Perl 5 , 37 или 36 байт
Попробуйте онлайн!
Оказывается, этот вопрос достаточно хорошо переводит на Perl, чтобы и там создать интересную загадку.
try
Эквивалент Perl вызывается (немного запутанно)eval
и определяет исключение, устанавливая@_
исключение, если оно произошло, и нулевую строку в противном случае. Таким образом,catch
блок реализуется путем сравнения@_
с пустой строкой.Это решение работает путем создания объекта (классом которого является программа в целом; вы можете использовать произвольные файлы Perl, такие как классы, что-то вроде обратного Java (где вы можете использовать произвольные классы, такие как файлы)). Это та
bless[]
часть, котораяbless
обычно появляется только глубоко внутри конструкторов, как примитив, который в первую очередь превращает вещи в объекты, но вы можете использовать его напрямую, если действительно хотите;[]
это распределитель памяти для объекта - конструктор списка, в этом case - и класс не указан, поэтому предполагается, что он выполняется в данный момент). Между тем, мы передаем нашему «классу» (то есть основному файлу) специальный метод сравнения со строкой с помощьюuse overload
этого метода и заставляем этот метод генерировать исключение (таким образом выход из цикла и решение головоломки); мы можем поставитьuse overload
в любом месте, и хотя он традиционно будет соответствовать другим определениям методов и приближаться к вершине файла, мы можем поместить его в промежуток, который нам дали, и он все еще работает. (Если мы поместим его в конец файла, мы можем опустить точку с запятой после него, что приведет к 36-байтовому решению, но это, вероятно, обман, так как это зависит от программы, в которой конечная точка с запятой находится в первую очередь, то есть не гарантировано.) На самом деле короче перегрузить операцию stringify и позволить Perl автоматически сгенерировать сравнение строк, чем это было бы, если бы перегрузить сравнение строк напрямую (потому что перегрузка некоторых операторов заставляет вас перегружать и другие операторы).Теперь все, что нам нужно сделать, это бросить наш объект, используя
die
. Завершаетсяeval
, затем, когда мы пытаемся сравнить$@
с пустой строкой (чтобы увидеть, было ли исключение), сравнение выдает другое исключение, и мы избегаем внешнегоeval
.источник