Dies ist durch die Syntax, die ich vermute, auf Java und C # beschränkt.
In diesem Programmierrätsel musst du Exception
s produzieren , die gefangen werden können, aber am Ende des Fangblocks erneut geworfen werden.
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
}
Sie können Code vor und nach diesem Snippet frei einfügen.
Der kürzeste Code, um den äußeren catch
Block zu erreichen , gewinnt.
code-golf
c#
java
programming-puzzle
user21634
quelle
quelle
Antworten:
C #, 46 (88 einschließlich Boilerplate)
Die
Abort()
Methode löst eine ThreadAbortException aus , eine spezielle Ausnahme, die am Ende jedes catch-Blocks automatisch erneut ausgelöst wird (sofern sie nichtThread.ResetAbort()
aufgerufen wird).quelle
C # 24 Zeichen
Beendet den inneren Try-Block, bevor er beabsichtigt ist, sodass ich eine Ausnahme außerhalb des Try-Blocks auslösen kann.
quelle
int a=1/0;
int a=
da In einigen Sprachen können Sie einfach den Ausdruck schreiben1/0
Java, 76 oder 31
Zählt nur die im Code vorgenommenen Einfügungen und ignoriert dabei neue Zeilen. 76, wenn Sie alles zählen, was ich hinzugefügt habe, 31, wenn Sie die erste und die letzte Zeile ausschließen, dh nur zählen
int a=1/0;try{}catch(Error e){}
.quelle
catch
Block hinzugefügt , was er nicht tat.Java (OpenJDK 8) ,
65 bis60 Byte (mit einer geringfügigen Änderung am Wrapper)Probieren Sie es online!
Erfordert, dass beide Instanzen von
catch (Exception …)
in der Frage in geändert werdencatch (Throwable …)
. Dies sollte in der Theorie mehr sicher, nicht weniger, aber es ermöglicht diese Lösung möglich zu sein.Ich habe 5 Bytes gegenüber der ersten Version dieser Antwort gespart, indem ich eine Methodenreferenz anstelle eines Lambda verwendet habe.
Java 4, 104 Byte (ungetestet, sollte mit dem Original-Wrapper funktionieren)
Probieren Sie es online! (Link geht zu einer Java 8-Implementierung, funktioniert also nicht)
Mithilfe von Funktionen, die aus modernen Java-Versionen entfernt wurden, kann sogar die Version des Puzzles gelöst werden, für die eine erforderlich ist
Exception
. Zumindest wahrscheinlich. (Java 4 ist mittlerweile sehr alt und ich kann mich nicht erinnern, welche Funktionen es enthielt und welche nicht. Wie man sieht, gab es damals in Java viel weniger Funktionen und diese waren daher ausführlicher; wir hatten keine Lambdas, also musste ich eine innere Klasse schaffen.)Erklärungen
Die meisten Lösungen für diese Frage sind in C # (zusammen mit einer Java-Lösung, die über die Verwendung von unsymmetrischen Klammern als Form der Code-Injection täuscht, und einer Perl-Lösung, die ebenfalls nicht in Java enthalten ist). Daher hielt ich es für sinnvoll, zu zeigen, wie dieses Rätsel auch in Java "richtig" gelöst werden kann.
Beide Programme sind praktisch identisch (die Tatsache, dass das erste Programm funktioniert, gibt mir die Gewissheit, dass das zweite Programm auch funktioniert, es sei denn, ich habe versehentlich eine Nicht-Java-4-Funktion verwendet,
Thread#stop
die in Java 5 veraltet war).Javas
Thread#stop
Methode funktioniert hinter den Kulissen, indem ein Wurfobjekt in den fraglichen Thread geworfen wird. Das für diesen Zweck vorgesehene Wurfobjekt istThreadDeath
(Error
insbesondere, weil die Leute oft versuchen, Ausnahmen zu überdecken und Javas Designer dies nicht wollten), obwohl Sie damit irgendwann nach der API alles werfen können (oder es gewohnt waren) Javas Designer erkannten, dass dies eine unglaublich schlechte Idee war, und entfernten die Version der Methode, die Argumente direkt in die Hand nimmt. Natürlich ist selbst die Version, die wirft,ThreadDeath
eine ziemlich riskante Operation, für die Sie nur wenige Garantien abgeben können (zum Beispiel können Sie damit dieses Rätsel lösen, was "nicht" möglich sein sollte, also sollten Sie es nicht tun benutze es, aber ab Java 8 funktioniert es immer noch.Dieses Programm erzeugt einen neuen Thread und fordert ihn auf, eine Ausnahme zwangsweise in den Haupt-Thread zurück zu werfen. Wenn wir Glück haben, geschieht dies zu einem Zeitpunkt, an dem wir außerhalb des inneren
catch
Blocks sind (wir können den äußerencatch
Block nicht verlassen, bis das Programm endet, da es eine Schleife gibt). Da wir die Schleife bereits hinzugefügt haben, ist es Byte-sparend, diese Schleife einfach zu verwenden, damit wir weiterhin Threads erstellen können, in der Hoffnung, dass einer von ihnen irgendwann das richtige Timing erreicht. Dies scheint normalerweise innerhalb weniger Sekunden zu geschehen.(Hinweis zu TIO: Die aktuelle Version von TIO ist sehr geneigt, dieses Programm zu einem frühen Zeitpunkt seiner Ausführung abzubrechen, vermutlich weil alle Threads erstellt wurden. Es kann mit TIO funktionieren, funktioniert jedoch nicht zuverlässig, weshalb häufig einige Versuche erforderlich sind Holen Sie sich die Ausgabe "Sie haben gewonnen!".)
quelle
C #
quelle
Perl 5 , 37 oder 36 Bytes
Probieren Sie es online!
Es stellt sich heraus, dass diese Frage gut genug in Perl übersetzt wird, um auch dort ein interessantes Rätsel zu machen. Perls
try
Äquivalent heißt (etwas verwirrend)eval
und gibt eine Ausnahme an, indem es@_
auf eine Ausnahme gesetzt wird, wenn sie aufgetreten ist, und ansonsten auf die Nullzeichenfolge. Als solches wird eincatch
Block durch Vergleichen@_
mit der Nullzeichenfolge implementiert .Diese Lösung erstellt ein Objekt (dessen Klasse das gesamte Programm ist; Sie können beliebige Perl-Dateien wie Klassen verwenden, ähnlich wie die Umkehrung von Java (wobei Sie beliebige Klassen wie Dateien verwenden können)). Das ist der
bless[]
Teil (bless
normalerweise erscheint er nur tief in Konstruktoren, als das Grundelement, das Dinge in erster Linie zu Objekten macht, aber Sie können ihn direkt verwenden, wenn Sie wirklich wollen),[]
der Speicherzuweiser für das Objekt - in diesem Fall ein Listenkonstruktor case - und die Klasse wird nicht angegeben, daher wird angenommen, dass es sich um die aktuell ausgeführte handelt). In der Zwischenzeit geben wir unserer "Klasse" (dh der Hauptdatei) eine benutzerdefinierte Methode zum Vergleichen mit einer Zeichenfolge überuse overload
und lassen diese Methode eine Ausnahme auslösen (wodurch die Schleife verlassen und das Rätsel gelöst wird). wir können das tatsächlich setzenuse overload
Überall, und obwohl es traditionell mit den anderen Methodendefinitionen übereinstimmt und sich dem oberen Rand der Datei nähert, können wir es in die Lücke setzen, die wir stattdessen erhalten haben, und es funktioniert immer noch. (Wenn wir es am Ende der Datei einfügen, könnten wir das Semikolon danach weglassen, was zu einer 36-Byte-Lösung führt, aber dies ist wohl ein Betrug, da es davon abhängt, dass das Programm an erster Stelle ein abschließendes Semikolon hat nicht garantiert.) Es ist tatsächlich kürzer, den Stringify-Vorgang zu überladen und Perl einen Stringvergleich daraus automatisch generieren zu lassen, als einen Stringvergleich direkt zu überladen (da das Überladen einiger Operatoren Sie dazu zwingt, auch andere Operatoren zu überladen).Jetzt müssen wir nur noch unser Objekt mit werfen
die
. Dieeval
endet, dann , wenn wir zu vergleichen , versuchen ,$@
auf die Null - Zeichenfolge (um zu sehen , ob es eine Ausnahme), wirft der Vergleich eine weitere Ausnahme und wir außen entweicheneval
.quelle