Ceci est limité à Java et C # par la syntaxe, je suppose.
Dans ce casse-tête de programmation, vous devez produire des Exception
s qui peuvent être capturés mais qui sont lancés à nouveau à la fin du bloc de capture.
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
}
Vous pouvez librement mettre du code avant et après cet extrait.
Le code le plus court pour atteindre le catch
bloc externe gagne.
code-golf
c#
java
programming-puzzle
user21634
la source
la source
Réponses:
C #, 46 (88 avec passe-partout)
La
Abort()
méthode déclenche une ThreadAbortException , qui est une exception spéciale qui est automatiquement renvoyée à la fin de chaque bloc catch (sauf si elleThread.ResetAbort()
est appelée).la source
Personnages C # 24
termine le bloc try interne avant l'intention, ce qui me permet de provoquer une exception en dehors du bloc try.
la source
int a=1/0;
?)int a=
? Certaines langues vous permettent d'écrire simplement l'expression1/0
Java, 76 ou 31
En comptant uniquement les insertions effectuées dans le code, en ignorant les nouvelles lignes. 76 si vous comptez tout ce que j'ai ajouté, 31 si vous excluez la première ligne et la dernière ligne, c'est-à-dire seulement le comptage
int a=1/0;try{}catch(Error e){}
.la source
catch
bloc après l'extrait de code, il ne l'a pas fait.Java (OpenJDK 8) ,
6560 octets (avec une légère modification du wrapper)Essayez-le en ligne!
Nécessite que les deux instances de
catch (Exception …)
la question soient remplacées parcatch (Throwable …)
. Cela devrait en théorie être plus sûr, pas moins, mais cela permet à cette solution d'être possible.J'ai économisé 5 octets sur la première version de cette réponse en utilisant une référence de méthode plutôt qu'un lambda.
Java 4, 104 octets (non testé, devrait fonctionner avec le wrapper d'origine)
Essayez-le en ligne! (le lien va vers une implémentation Java 8, donc ne fonctionnera pas)
En utilisant des fonctionnalités qui ont été supprimées des versions modernes de Java, il est possible de résoudre même la version du puzzle qui nécessite un
Exception
. Probablement, au moins. (Java 4 est très ancien maintenant et je ne me souviens plus quelles fonctionnalités il contenait et ne contenait pas. Comme on peut le voir, il y avait beaucoup moins de fonctionnalités à l'époque à Java et il était donc plus détaillé; nous n'avions pas lambdas, j'ai donc dû créer une classe intérieure.)Explications
La plupart des solutions à cette question sont en C # (avec une solution Java qui triche via l'utilisation de crochets non équilibrés comme forme d'injection de code, et une solution Perl qui n'est pas non plus en Java). J'ai donc pensé qu'il valait la peine d'essayer de montrer comment ce puzzle peut être résolu "correctement" en Java aussi.
Les deux programmes sont effectivement identiques (donc le fait que le premier programme fonctionne me donne une grande confiance que le deuxième programme fonctionnerait aussi, sauf si j'ai accidentellement utilisé une fonctionnalité non Java-4; a
Thread#stop
été dépréciée dans Java 5).La
Thread#stop
méthode de Java fonctionne, en arrière-plan, en provoquant le lancement d'un objet jetable dans le thread en question. Le jetable prévu à cet effet estThreadDeath
(unError
, en particulier parce que les gens essaient souvent de détecter les exceptions et que les concepteurs de Java ne voulaient pas que cela se produise), bien qu'il vous permette de lancer quoi que ce soit (ou l'habitude; à un moment donné après que l'API ait été conçu, les concepteurs de Java ont réalisé que c'était une idée incroyablement mauvaise et ont supprimé la version de la méthode qui prend les arguments au clair). Bien sûr, même la version qui lanceThreadDeath
est une opération assez risquée pour laquelle vous pouvez faire peu de garanties (par exemple, cela vous permet de résoudre ce puzzle, quelque chose qui "ne devrait pas" être possible), donc vous n'êtes pas censé l'utiliser, mais à partir de Java 8, cela fonctionne toujours.Ce programme fonctionne en générant un nouveau thread et en lui demandant de renvoyer de force une exception dans le thread principal. Si nous sommes chanceux, cela se fera à un moment où nous serons en dehors du
catch
bloc interne (nous ne pouvons pas échapper aucatch
bloc externe jusqu'à la fin du programme, car il y a une boucle autour de lui). Parce que nous avons déjà ajouté la boucle de manière pratique, il est économiseur d'octets d'utiliser simplement cette boucle pour nous permettre de continuer à créer des threads, dans l'espoir que l'un d'entre eux atteindra finalement le bon timing. Cela semble normalement se produire en quelques secondes.(Remarque TIO: la version actuelle de TIO est assez encline à tuer ce programme au début de son exécution, probablement en raison de tous les threads créés. Il peut fonctionner sur TIO, mais ne fonctionne pas de manière fiable, si souvent quelques tentatives sont nécessaires pour obtenez la sortie "Vous avez gagné!".)
la source
C #
la source
Perl 5 , 37 ou 36 octets
Essayez-le en ligne!
Il s'avère que cette question se traduit assez bien en Perl pour y créer un puzzle intéressant. L'
try
équivalent de Perl est appelé (un peu confus)eval
, et spécifie une exception en définissant@_
une exception si elle s'est produite, et la chaîne nulle sinon. En tant que tel, uncatch
bloc est implémenté via une comparaison@_
avec la chaîne nulle.Cette solution fonctionne en créant un objet (dont la classe est le programme dans son ensemble; vous pouvez utiliser des fichiers Perl arbitraires comme des classes, un peu comme l'inverse de Java (où vous pouvez utiliser des classes arbitraires comme des fichiers)). C'est la
bless[]
partie (bless
n'apparaît normalement qu'au fond des constructeurs, comme la primitive qui transforme les choses en objets en premier lieu, mais vous pouvez l'utiliser directement si vous le souhaitez vraiment;[]
est l'allocateur de mémoire pour l'objet - un constructeur de liste, dans ce case - et la classe n'est pas donnée, elle est donc supposée être celle en cours d'exécution). Pendant ce temps, nous donnons à notre "classe" (c'est-à-dire le fichier principal) une méthode de comparaison à chaîne personnalisée viause overload
, et faisons en sorte que cette méthode lève une exception (rompant ainsi la boucle et résolvant le casse-tête); nous pouvons mettreuse overload
n'importe où, et bien que cela irait traditionnellement avec les autres définitions de méthode et se rapprocherait du haut du fichier, nous pouvons le placer dans l'espace qui nous a été donné à la place et cela fonctionne toujours. (Si nous le mettons à la fin du fichier, nous pourrions omettre le point-virgule après lui, ce qui conduit à une solution de 36 octets, mais cela triche sans doute car cela dépend du programme ayant un point-virgule de fin en premier lieu, qui est non garanti.) Il est en fait plus court de surcharger l'opération de stringify et de laisser Perl générer automatiquement une chaîne de comparaison à partir de cela, qu'il ne le serait de surcharger directement la chaîne de comparaison (car la surcharge de certains opérateurs vous oblige à surcharger d'autres opérateurs également).Maintenant, tout ce que nous avons à faire est de lancer notre objet en utilisant
die
. Le seeval
termine, puis lorsque nous essayons de comparer$@
à la chaîne nulle (pour voir s'il y avait une exception), la comparaison lève une autre exception et nous échappons à l'extérieureval
.la source