Sądzę, że jest to ograniczone do Java i C # przez składnię.
W tej łamigłówce programistycznej masz wytworzyć Exception
s, które można złapać, ale które są rzucane ponownie na końcu bloku 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
}
Możesz swobodnie wstawiać kod przed i po tym fragmencie.
catch
Wygrywa najkrótszy kod do osiągnięcia zewnętrznego bloku.
code-golf
c#
java
programming-puzzle
użytkownik21634
źródło
źródło
Odpowiedzi:
C #, 46 (88 łącznie z płytą grzewczą)
Abort()
Sposób podnosi ThreadAbortException , który jest wyjątek specjalny, który jest automatycznie rethrown na końcu każdego bloku zatrzaskowej (o ile nieThread.ResetAbort()
jest wywoływany).źródło
C # 24 znaków
kończy wewnętrzny blok try przed wcześniejszym planowaniem, pozwalając mi na spowodowanie wyjątku poza blokiem try.
źródło
int a=1/0;
int a=
tam Niektóre języki pozwalają po prostu napisać wyrażenie1/0
Java, 76 lub 31
Licząc tylko wstawki wykonane w kodzie, ignorując nowe wiersze. 76 jeśli policzysz wszystko , co dodałem, 31 jeśli wykluczysz pierwszą linię i ostatnią linię, tj. Tylko liczenie
int a=1/0;try{}catch(Error e){}
.źródło
catch
blok po fragmencie, nie zrobił tego.Java (OpenJDK 8) ,
6560 bajtów (z niewielką modyfikacją opakowania)Wypróbuj online!
Wymaga zmiany obu wystąpień
catch (Exception …)
pytaniacatch (Throwable …)
. Teoretycznie powinno to być bardziej bezpieczne, nie mniej, ale umożliwia to rozwiązanie.Zapisałem 5 bajtów w pierwszej wersji tej odpowiedzi, używając odwołania do metody zamiast lambda.
Java 4, 104 bajty (nieprzetestowane, powinien działać z oryginalnym opakowaniem)
Wypróbuj online! (link prowadzi do implementacji Java 8, więc nie będzie działać)
Korzystając z funkcji, które zostały usunięte z nowoczesnych wersji Javy, możliwe jest rozwiązanie nawet wersji układanki, która wymaga
Exception
. Prawdopodobnie przynajmniej. (Java 4 jest już bardzo stara i nie pamiętam, jakie funkcje ona zawierała, a których nie zawierała. Jak widać, w Javie było wtedy o wiele mniej funkcji i dlatego była bardziej szczegółowa; nie mieliśmy lambdas, więc musiałem stworzyć wewnętrzną klasę.)Objaśnienia
Większość rozwiązań tego pytania jest w języku C # (wraz z rozwiązaniem Java, które oszukuje za pomocą niezrównoważonych nawiasów jako formy wstrzykiwania kodu, oraz rozwiązaniem Perla, które również nie jest w Javie). Pomyślałem więc, że warto spróbować pokazać, jak tę zagadkę można rozwiązać „poprawnie” również w Javie.
Oba programy są w rzeczywistości identyczne (stąd fakt, że pierwszy program działa, daje mi dużą pewność, że drugi program również zadziała, chyba że przypadkowo użyłem funkcji innej niż Java-4;
Thread#stop
został wycofany w Javie 5).Thread#stop
Metoda Javy działa za kulisami, powodując wrzucenie rzucanego przedmiotu do wątku. Rzucanie przeznaczone do tego celu jestThreadDeath
(Error
szczególnie dlatego, że ludzie często próbują uchwycić wyjątki, a projektanci Javy nie chcieli, aby tak się działo), chociaż pozwala to na rzucanie czegokolwiek (lub przywykło; w pewnym momencie po API był zaprojektowane, projektanci Javy zdali sobie sprawę, że był to niesamowicie zły pomysł i usunęli wersję metody, która przyjmuje argumenty wprost). Oczywiście nawet wersja, która rzuca,ThreadDeath
jest dość ryzykowną operacją, na którą możesz zrobić kilka gwarancji (na przykład pozwala rozwiązać tę zagadkę, co „nie powinno być możliwe”), więc nie powinieneś użyj go, ale od wersji Java 8 nadal działa.Ten program działa, odradzając nowy wątek i prosząc go, aby siłą wrzucił wyjątek z powrotem do głównego wątku. Jeśli będziemy mieli szczęście, zrobimy to w momencie, gdy znajdziemy się poza
catch
blokiem wewnętrznym (nie możemy uciec zcatch
bloku zewnętrznego , dopóki program się nie skończy, ponieważ wokół niego jest pętla). Ponieważ pętla została już dogodnie dodana, oszczędzanie bajtów polega na zwykłym użyciu tej pętli, aby umożliwić nam tworzenie wątków w nadziei, że jeden z nich ostatecznie osiągnie właściwy czas. Wydaje się, że dzieje się to zwykle w ciągu kilku sekund.(Uwaga TIO: obecna wersja TIO jest skłonna zabić ten program na wczesnym etapie jego wykonywania, prawdopodobnie ze względu na wszystkie tworzone wątki. Może działać na TIO, ale nie działa niezawodnie, więc często potrzeba kilku prób, aby uzyskać wynik „Wygrałeś!”).
źródło
DO#
źródło
Perl 5 , 37 lub 36 bajtów
Wypróbuj online!
Okazuje się, że to pytanie przekłada się na Perla wystarczająco dobrze, aby stworzyć tam również interesującą zagadkę. Odpowiednik Perla
try
nazywa się (trochę myląco)eval
i określa wyjątek poprzez ustawienie@_
wyjątku, jeśli wystąpił, a łańcuch zerowy w przeciwnym razie. Jako taki,catch
blok jest implementowany poprzez porównywanie@_
z łańcuchem zerowym.To rozwiązanie działa, tworząc obiekt (którego klasą jest program jako całość; możesz używać dowolnych plików Perla, takich jak klasy, coś w rodzaju odwrotnej strony Javy (gdzie możesz używać dowolnych klas, takich jak pliki)). To jest
bless[]
część (bless
zwykle pojawia się tylko głęboko w konstruktorach, jako prymityw, który przede wszystkim zamienia rzeczy w obiekty, ale możesz go użyć bezpośrednio, jeśli naprawdę chcesz;[]
jest to alokator pamięci dla obiektu - konstruktor listy, w tym case - i klasa nie jest podana, więc zakłada się, że jest aktualnie wykonywana). Tymczasem dajemy naszej „klasie” (tj. Plikowi głównemu) niestandardową metodę porównywania z ciągiem znakówuse overload
i robimy , aby ta metoda generowała wyjątek (w ten sposób wyłamując się z pętli i rozwiązując zagadkę); możemy faktycznie umieścićuse overload
gdziekolwiek i chociaż tradycyjnie wchodziłby w inne definicje metod i zbliżał się do górnej części pliku, możemy umieścić go w luce, którą nam podano, i nadal działa. (Jeśli umieścimy go na końcu pliku, możemy pominąć średnik po nim, co prowadzi do rozwiązania 36-bajtowego, ale jest to prawdopodobnie oszustwo, ponieważ zależy od tego, czy program ma w pierwszej kolejności średnik końcowy, który jest nie jest gwarantowane.) W rzeczywistości jest krótsze, aby przeciążyć operację strunizacji i pozwolić Perlowi na automatyczne wygenerowanie łańcucha porównującego z tego, niż byłoby to przeciążenie porównania łańcucha bezpośrednio (ponieważ przeciążenie niektórych operatorów zmusza cię do przeciążenia również innych operatorów).Teraz wystarczy rzucić naszym przedmiotem
die
. Weval
odebrane, a następnie, gdy staramy się porównać$@
do łańcucha pustego (aby sprawdzić, czy nie był wyjątkiem), porównanie rzuca kolejny wyjątek i uciec na zewnątrzeval
.źródło