Supongo que esto está limitado a Java y C # por la sintaxis.
En este rompecabezas de programación, debes producir Exception
s que se puedan atrapar pero que se vuelvan a lanzar al final del bloque de captura.
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
}
Puedes poner código libremente antes y después de este fragmento.
El código más corto para alcanzar el catch
bloque exterior gana.
code-golf
c#
java
programming-puzzle
usuario21634
fuente
fuente
Respuestas:
C #, 46 (88 incluyendo repetitivo)
El
Abort()
método genera una ThreadAbortException , que es una excepción especial que se vuelve a generar automáticamente al final de cada bloque catch (a menos queThread.ResetAbort()
se llame).fuente
Personajes C # 24
termina el bloque de prueba interno antes de lo previsto, lo que me permite causar una excepción fuera del bloque de prueba.
fuente
int a=1/0;
?)int a=
allí? Algunos idiomas le permiten simplemente escribir la expresión1/0
Java, 76 o 31
Contando solo las inserciones realizadas en el código, ignorando nuevas líneas. 76 si cuenta todo lo que he agregado, 31 si excluye la primera línea y la última línea, es decir, solo cuenta
int a=1/0;try{}catch(Error e){}
.fuente
catch
bloque después del fragmento, no lo hizo.Java (OpenJDK 8) ,
6560 bytes (con una ligera modificación en el contenedor)Pruébalo en línea!
Requiere que ambas instancias de
catch (Exception …)
la pregunta se cambien acatch (Throwable …)
. En teoría, esto debería ser más seguro, no menos, pero permite que esta solución sea posible.Ahorré 5 bytes en la primera versión de esta respuesta mediante el uso de una referencia de método en lugar de una lambda.
Java 4, 104 bytes (no probado, debería funcionar con el contenedor original)
Pruébalo en línea! (el enlace va a una implementación de Java 8, por lo tanto no funcionará)
Usando características que se han eliminado de las versiones modernas de Java, es posible resolver incluso la versión del rompecabezas que requiere un
Exception
. Probablemente, al menos. (Java 4 es muy antiguo por ahora y no puedo recordar qué características tenía y no contenía. Como se puede ver, había muchas menos características en Java en ese momento y, por lo tanto, era más detallado; no teníamos lambdas, así que tuve que crear una clase interna).Explicaciones
La mayoría de las soluciones a esta pregunta están en C # (junto con una solución Java que engaña mediante el uso de corchetes desequilibrados como una forma de inyección de código, y una solución Perl que tampoco está en Java). Así que pensé que valdría la pena intentar mostrar cómo este rompecabezas también se puede resolver "correctamente" en Java.
Ambos programas son efectivamente idénticos (por lo tanto, el hecho de que el primer programa funcione me da mucha confianza en que el segundo programa también funcionaría, a menos que accidentalmente haya usado una característica que no sea Java-4;
Thread#stop
fue desaprobada en Java 5).El
Thread#stop
método de Java funciona, detrás de escena, al hacer que se arroje un elemento arrojable al hilo en cuestión. Lo que se puede usar para ese propósito esThreadDeath
(yError
, específicamente, porque la gente a menudo trata de ocultar las excepciones y los diseñadores de Java no querían que eso sucediera), aunque le permite lanzar cualquier cosa (o solía hacerlo; en algún momento después de que la API fue diseñado, los diseñadores de Java se dieron cuenta de que esta era una idea increíblemente mala y eliminaron la versión del método que toma los argumentos directamente). Por supuesto, incluso la versión que arrojaThreadDeath
es una operación bastante arriesgada sobre la que puede hacer pocas garantías (por ejemplo, le permite resolver este rompecabezas, algo que "no debería" ser posible), por lo que no debe hacerlo úsalo, pero a partir de Java 8, todavía funciona.Este programa funciona generando un nuevo hilo y pidiéndole que arroje una excepción al hilo principal. Si tenemos suerte, lo hará en un momento dado cuando estemos fuera del
catch
bloque interno (no podemos escapar delcatch
bloque externo hasta que finalice el programa, porque hay un bucle a su alrededor). Debido a que ya tenemos el bucle convenientemente agregado, es un ahorro de bytes simplemente usar ese bucle para permitirnos seguir creando subprocesos, con la esperanza de que uno de ellos finalmente llegue al momento correcto. Esto normalmente parece suceder en un par de segundos.(Nota de TIO: la versión actual de TIO está bastante inclinada a matar este programa al principio de su ejecución, presumiblemente debido a todos los hilos que se están creando. Puede funcionar en TIO, pero no funciona de manera confiable, por lo que a menudo se requieren algunos intentos para obtén la salida "¡Ganaste!")
fuente
C#
fuente
Perl 5 , 37 o 36 bytes
Pruébalo en línea!
Resulta que esta pregunta se traduce en Perl lo suficientemente bien como para hacer un rompecabezas interesante allí también. El
try
equivalente de Perl se llama (un poco confuso)eval
, y especifica una excepción estableciendo@_
una excepción si ocurrió, y la cadena nula de lo contrario. Como tal, uncatch
bloque se implementa mediante la comparación@_
con la cadena nula.Esta solución funciona creando un objeto (cuya clase es el programa en su conjunto; puede usar archivos Perl arbitrarios como clases, algo así como el reverso de Java (donde puede usar clases arbitrarias como archivos)). Esa es la
bless[]
parte (bless
normalmente solo aparece en el interior de los constructores, como la primitiva que convierte las cosas en objetos en primer lugar, pero puede usarla directamente si realmente lo desea;[]
es el asignador de memoria para el objeto, un constructor de listas, en este case - y la clase no se da, por lo que se supone que es la que se está ejecutando actualmente). Mientras tanto, le damos a nuestra "clase" (es decir, el archivo principal) un método personalizado de comparación a cadena a través deuse overload
, y hacemos que ese método arroje una excepción (rompiendo así el bucle y resolviendo el rompecabezas); en realidad podemos poner eluse overload
en cualquier lugar, y aunque tradicionalmente iría con las otras definiciones de métodos y se acercaría a la parte superior del archivo, podemos colocarlo en el espacio que se nos ha dado y aún funciona. (Si lo colocamos al final del archivo, podríamos omitir el punto y coma después de él, lo que llevaría a una solución de 36 bytes, pero esto podría decirse que es una trampa, ya que depende del programa que tenga un punto y coma final en primer lugar, que es no está garantizado.) En realidad, es más corto sobrecargar la operación stringify y dejar que Perl genere automáticamente una comparación de cadenas a partir de eso, de lo que sería sobrecargar la comparación de cadenas directamente (porque la sobrecarga de algunos operadores también obliga a sobrecargar a otros operadores).Ahora, todo lo que tenemos que hacer es lanzar nuestro objeto usando
die
. Loseval
termina, a continuación, cuando se intenta comparar$@
a la cadena nula (a ver si había una excepción), la comparación arroja otra excepción y que escapan al exterioreval
.fuente