Inspirado por este comentario ...
¡Gracias a los usuarios Step Hen , Wheat-Wizard y Dennis por ayudarme a solidificar la especificación de este desafío antes de publicarlo!
Este es el hilo del ladrón! Para el hilo de los policías, vaya aquí
En este desafío , tiene la tarea de ejecutar un código que haga que su lenguaje ya no satisfaga nuestros criterios de ser un lenguaje de programación. En ese desafío, eso significa hacer que el idioma ya no pueda ...
Tomar entrada y salida numérica
Suma dos números juntos
Prueba si cierto número es primo o no.
Esta es una de policías y ladrones desafío, donde hay dos retos diferentes con dos objetivos diferentes: Los policías se trate de escribir un código que hace que el lenguaje sobre todo inservible, y los ladrones tratarán de encontrar la solución oculto que permite a la policía para recuperar su lenguaje.
Los policías escribirán dos fragmentos de código:
Uno que hace que su lenguaje sea prácticamente inutilizable, por ejemplo, eliminando las funciones integradas para tomar entradas / salidas y operaciones numéricas. Este código no puede bloquearse o salir. Debería ser posible agregar código al final de este fragmento, y ese código será evaluado . Y
Un fragmento de código que toma dos números como entrada, los agrega y genera su suma. Este fragmento debe funcionar correctamente incluso después de ejecutar el primer fragmento. Cuando los dos fragmentos se combinan, deben formar un programa completo que agregue dos números o definir una función que agregue dos números. Este fragmento probablemente dependerá de un comportamiento oscuro y será difícil de encontrar.
Los policías también elegirán cualquier método estándar de entrada y salida . Sin embargo, deben revelar exactamente qué formato (entrada y salida) están utilizando. Para descifrar su respuesta, debe seguir el mismo formato de entrada / salida, o su crack no cuenta.
La respuesta de un policía siempre revelará
El primer fragmento (obviamente no el segundo).
Idioma (incluida la versión menor, ya que la mayoría de las presentaciones probablemente dependerán de casos extraños)
Formato IO, incluso si es una función o un programa completo. Los ladrones deben usar el mismo formato para ser un crack válido.
Cualquier caso marginal extraño requerido para que su respuesta funcione. Por ejemplo, solo se ejecuta en Linux , o requiere una conexión a Internet .
Como ladrón, debes mirar una de las presentaciones de la policía e intentar descifrarla. Puede descifrarlo escribiendo cualquier fragmento válido que pueda funcionar como fragmento 2 (sumando dos números juntos después de que el idioma quede prácticamente inutilizable). Este no tiene que ser el mismo fragmento que el policía escribió originalmente. Una vez que tenga una respuesta descifrada, publique su código como respuesta en este hilo y publique un enlace a su respuesta como un comentario en la respuesta del policía. Luego, esa publicación se editará para indicar que se ha descifrado.
Aquí hay un ejemplo. Para el primer fragmento, es posible que vea el siguiente programa de Python 3 como respuesta de la policía:
Python 3
print=None
Toma entrada de STDIN y salida a STDOUT
Un segundo fragmento válido podría ser
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
Esto es válido porque tomará dos números como entrada y generará su suma incluso si une los dos fragmentos, p. Ej.
print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
Esta es una grieta válida para su respuesta.
Si la respuesta de un policía permanece sin descifrar durante una semana entera, puede editar en su segundo fragmento e indicar que su respuesta ahora es segura . Una vez que se edita para que sea seguro, ya no puede intentar descifrarlo. Si no lo editan como seguro, puede continuar intentando descifrarlo hasta que lo hagan.
El ganador del hilo del ladrón es el usuario que ha obtenido la mayor cantidad de respuestas, siendo el desempate el momento en que llegaron a N grietas. (por lo tanto, si dos usuarios diferentes tienen 5 grietas, por ejemplo, el usuario que publicó su quinta grieta primero es el ganador) Después de que haya pasado el tiempo suficiente, aceptaré la respuesta del ganador con la mayor cantidad de votos.
¡Que te diviertas!
Aclaraciones de reglas
El primer fragmento debe ejecutarse correctamente sin tomar ninguna entrada . Puede generar lo que desee, y esta salida será ignorada. Siempre que el fragmento esté hecho, el segundo fragmento se ejecutará correctamente.
El segundo fragmento debe ejecutarse para que su respuesta sea válida. Esto significa una respuesta como
import sys sys.exit()
no es válido porque no rompe el idioma. Simplemente se cierra.
Después de estar seguro, su puntaje es el recuento de bytes de ambos fragmentos .
Esto se remonta a Por favor, revele los casos extremos extraños necesarios para que su respuesta funcione ... Su envío debe contener suficiente información antes de ser revelado para ser reproducible después de ser revelado. Esto significa que si su respuesta se vuelve segura y luego edita en: Aquí está mi respuesta. Ah, por cierto, esto solo funciona si lo ejecutas en Solaris, ¡bromeas! su respuesta no es válida y se eliminará y no se considerará elegible para ganar.
Se permite que el segundo fragmento se bloquee después de generar la suma. Siempre que la salida sea correcta (por ejemplo, si elige enviar a STDERR, y luego obtiene un montón de información de bloqueo, esto no es válido)
Tabla de clasificación
Aquí hay una lista de cada usuario con al menos un crack, ordenado por puntaje y luego por nombre (alfabético). Si envía un crack, actualice su puntaje en consecuencia.
#User #Score
Ilmari Karonen 8
Dennis 5
Olivier Grégoire 4
Sisyphus 3
Veedrac 3
Arnold Palmer 2
Bruce Forte 2
DJMcMayhem 2
Dom Hastings 2
ppperry 2
1bluston 1
2012rcampion 1
Ben 1
BlackCap 1
Christian Sievers 1
Cody Gray 1
HyperNeutrino 1
Joshua 1
Kaz 1
Mark 1
Mayube 1
Xnor 1
zbw 1
fuente
SecurityManager
que estuviera dentro del alcance ... Sin embargo, también puedes leerSystem.in
en este punto, porque aún no está cerrado.sun.awt.SecurityManager
y"sun.awt.command"
son dependientes de la plataforma y no son parte de Java .System.getProperties().get("blah")
(ya que solo bloqueé el acceso aSystem.getProperty
, noSystem.getProperties
), ¡pero esto es lo suficientemente bueno! ¡Bien hecho!C (GCC / Linux) por Sisyphus
Este fragmento cierra la función proporcionada e inicia una nueva (inyección de código clásica), que se redefine a sí misma
close
para que, en lugar de cerrar el fd, ejecute nuestro código deseado.fuente
Python, la solución de Wheat Wizard aquí
Quiero decir, puedes volver a establecer el límite de recursión y no pasa nada malo ...
Funciona en TIO
Nota
Esta es mi primera presentación de CnR, así que si esto rompe alguna regla, dígame y lo eliminaré.
fuente
os.sys
, si eso hace la diferencia: PHaskell por Ben
Todavía tengo números literales y caracteres (uso
0
,'0'
y'-'
),[a..]
y[a..b]
que son muy útiles. Y tengo unario-
, pero podría prescindir.Recreo
++
para implementarr
(reverse
) y definirt
yts
cuáles sontail
ytails
.x a b
devuelve eln
elemento th deb
, donden
es la longitud dea
menos uno.x
generalmente se podría definir comosnd.last.zip
. La funciónd
toma una lista y devuelve una lista con los elementos de esas posiciones que son múltiplos de diez.l!!s
devuelve eln
elemento th del
, dondes
es la representación de cadena invertida den
.+
devuelve como entero la suma de dos números naturales dados como cadenas invertidas, del mismo modo-
para la diferencia.add
devuelve como entero la suma de dos enteros posiblemente negativos dados como cadenas.Me pregunto si esto es algo similar a lo que Ben tenía en mente.
fuente
:
estaba dentro del alcance incluso conNoImplicitPrelude
y sin importar nada.C (gcc) de Conor O'Brien
Pruébalo en línea!
fuente
Python 2 por Wheat Wizard (cuarta iteración)
Pruébalo en línea!
Sin exploits, solo una función para agregar usando solo caracteres
' &)(,.:[]a`cdfijmonrt~'
, según lo previsto (en realidad solo'(),.:[]`acdfijmnort'
).No hice ningún intento de hacerlo breve; Acabo de escribir subexpresiones para valores intermedios como 0 y la cadena vacía y sustituida por cadenas en esos.
Pruébalo en línea!
La idea central es que el formato de cadena
'{0:5}'.format('1')
agrega el número cero a una longitud5
similar'1 '
. Mediante la concatenación de dos cadenas de este tipo''.join
, la suma de su longitud es la suma de los números de entrada. Luego, añadimos0
a al final y llamamos.find()
a la posición final, que es la suma.La cadena
'{0:5}'
para formatear se produce extrayendo los{:}
caracteres de las cadenas de los diccionarios, creados condict
. La cadena repr de cada sumando sucesivo se coloca donde estarían los 5. Quería usar un dict como él{0:5}
mismo, pero su repr incluye un espacio que lo estropeó.Las entradas de 0 desordenan el proceso porque el subcadena tiene una longitud mínima de 1. En
and/or
este caso, tenemos aquellos con un para dar la cadena vacía.fuente
int([]in[])
de manera simpleint()
ya que ambos generarán 0.Haskell, por Laikoni
fuente
Ensamblaje x86 de 16 bits en modo real, por Joshua
Explicación:
La "ruptura" introducida por el código de Joshua es la configuración del indicador de trampa (TF), que pone la CPU en modo de un solo paso. Esto significa que solo se ejecutará una sola instrucción a la vez, antes de que la CPU se detenga (trampas) con una interrupción de tipo 1. Esto es lo que permite a los depuradores implementar un solo paso de código, bastante útil allí, ¡pero un verdadero PITA si desea ejecutar el código fuera del contexto de un depurador!
Es la siguiente sección de código que activa el indicador de trampa:
La implementación del indicador de trampa significa que tenemos la oportunidad de ejecutar exactamente una instrucción antes de las trampas de la CPU, que es la que viene inmediatamente después del
POPF
aquí. Entonces, necesitamos hacer que este cuente.El truco es la
INT 3
instrucción, que invoca la interrupción número 3. Hay dos razones por las cuales esto funciona para "descifrar" el código:La bandera de la trampa se borra en los manejadores de interrupciones. Esto es solo parte del diseño de Intel, pero presumiblemente se hizo por razones básicas de cordura. Recuerde que la aplicación de la bandera trampa es que una interrupción de tipo 1 se invoca después de la ejecución de cada instrucción, por lo que si TF no se borra,
INT 1
lo haría en sí desencadenar una interrupción-sería interrupciones hasta el fondo. Además, tener interrupciones claras TF simplemente hace que sea más fácil depurar el código, al igual que un IDE que pasa automáticamente por las llamadas a las funciones de la biblioteca.La forma en que interrumpe el trabajo es esencialmente la misma que en un lugar lejano
CALL
. Invocan al controlador de interrupciones cuya dirección se almacena en la posición correspondiente en la tabla de vectores de interrupción global. Como esta tabla comienza en la dirección0x0000:0000
y se almacena en unsegment:offset
formato de 4 bytes , calcular la dirección es tan simple como multiplicar 4 por el vector / número de interrupción. En este caso, invocamos la interrupción 3, por lo que sería 4 × 3 = 12.... y notarás que Joshua pensativo preparó esto para nosotros. Antes de habilitar el indicador de trampa, tiene el siguiente código:
que establece
0x0000:000C
(el manejador de interrupciones paraINT 3
) enBP:SI
. Eso significa que cada vez queINT 3
se invoca, empuja el registro de BANDERAS a la pila, seguido de la dirección de retorno, y luego se bifurcaBP:SI
, lo que nos permite comenzar a ejecutar el código nuevamente, en un contexto en el que la bandera trampa está apagada.Todo es cuesta abajo después
INT 3
. Todo lo que necesitamos hacer es sumar dos números e imprimir el resultado. Excepto que esto no es tan simple en lenguaje ensamblador como lo sería en otros idiomas, así que aquí es donde se gasta la mayor parte del código.Joshua está permitiendo que el ladrón especifique cualquier mecanismo de E / S que desee , por lo que estoy adoptando el enfoque simplista de suponer que los valores se pasan en los registros
DX
yCX
. Eso es razonable, ya que su código de "prólogo" no los cubre en ninguna parte.La salida se realiza almacenando bytes ASCII directamente en la memoria de video. El búfer de video comienza en
0xB800:0000
un modo de texto CGA, EGA y / o VGA, por lo que comenzamos a imprimir allí. El formato es: carácter en el byte bajo y atributo de color en el byte alto. Eso significa que cada carácter está en un desplazamiento de 2 bytes. Simplemente iteramos a través de cada uno de los dígitos en el número (base-10), convirtiéndolos a ASCII e imprimiéndolos uno a la vez en la pantalla. Sí, esto es mucho código. No hay funciones de biblioteca que nos ayuden en lenguaje ensamblador. Es casi seguro que esto puede optimizarse aún más, pero me cansé de trabajar en ello ...Después de que se muestra la salida, se permite que el código se bloquee o haga lo que sea, por lo que simplemente eliminamos las interrupciones y detenemos la CPU.
fuente
INT 3
y termino de inmediato con las instrucciones que siguen, así que simplemente seguí con él. Tal vez tiene algo que ver con mi entorno de prueba?CLI
solo deshabilitaría las interrupciones de hardware, pero incluso siHLT
pasara el , pensarías que no funcionaría y ejecutaría el códigol
inmediatamente después.Python 2 por TwiNight
Pruébalo en línea!
fuente
Python 3 , el segundo desafío de ppperry
Wow, esto fue divertido! Disfruté resolviendo esto.
Editar: OK, lo arreglé. Parece que las clases estaban en un índice diferente en la lista de subclases en TIO que en mi computadora, así que lo hice funcionar para ambos y agregué un TIO.
Pruébalo en línea!
fuente
sys.excepthook is missing
?sys.excepthook
, pero habrá una causa real que aparece en algún lugar allí.)IndexError('list index out of range',)
. Está en la línea con la definición de_io_RawIOBase
._io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]
debería funcionar en todas partes.Haskell por zbw
¿No se puede ejecutar el código en tiempo de ejecución? ¡Ejecútalo en tiempo de compilación!
Esto fue muy divertido, no conocía la plantilla haskell antes de este desafío.
fuente
Gelatina por hiper neutrino
Súper simple Newline hace que no se llame al primer enlace.
Pruébalo en línea!
fuente
Python 2 por Wheat Wizard
Pruébalo en línea!
fuente
Java por LordFarquaad
Bloquear el acceso a los objetos en el nivel de origen fue realmente inteligente (y molesto durante las pruebas), ¡bien hecho!
fuente
ClassLoader
hubiera sido sombreado?"".getClass().getClassLoader()
. El sombreado suele ser solo un problema en el que debe pensar una vez y luego está bien. Incluso podrías hacer sombraObject
, todavía podría resolver esto. Ok, podrías forzarme a la solución de 1kb, pero es posible.Ruby por histocrat
Pruébalo en línea!
fuente
Inform 7, por Ilmari Karonen
Abuso flagrante de sustantivos ambiguos ... Mi código comienza con
factory is a room
. La línea anterior es el código del policía. Escribaadd 1 and 1
para obtener 2, por ejemplo.fuente
Java, Roman Gräf
Establece
stdout
ystderr
vuelve a sus valores iniciales.Creo que puedo usar el nombre completo en lugar de una importación, si me equivoco, corríjame (esta es mi primera publicación aquí). Probablemente esto también se pueda hacer usando la reflexión.
Editar: aquí hay una solución reflexiva que usa solo
java.lang.reflect.*
:fuente
stdin
,stdout
ystderr
se almacenan en otro lugar! Ni siquiera necesita usarlosetOut
ysetErr
simplemente puede usarloPrintStream
directamente.JavaScript de Daniel Franklin
Esto podría considerarse una solución ligeramente engañosa, pero funciona para mí en Chromium 59 / Linux, incluso si también recibo una advertencia que dice:
PD. Aquí hay otra grieta, esta vez sin advertencias:
fuente
prompt()- -prompt()
ahorra dos bytesJava 8 por Olivier Grégoire
Una grieta enormemente detallada para un desafío enormemente detallado. :) El dolor de trabajar indirectamente con clases que no puedes nombrar es palpable.
Pruébalo en línea!
PD. Aquí está mi intento anterior, escrito antes de que Olivier aclarara que la entrada debía tomarse mediante argumentos de línea de comando. A diferencia del crack anterior, este no es específico de Linux.
Pruébalo en línea!
fuente
String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");
que no es específica de Linux, pero utiliza lo que parece ser una propiedad no documentada establecida por algunas JVM.C # (.NET Core) por raznagul
Supongo que esta no era la solución prevista.
fuente
/dev/std*
eso. Inicialmente apunté a un enfoque similar, pero no pude encontrar ninguna manera fácil de abrir transmisiones para stdin / out sin acceso a System.Console, por lo que opté por la reflexión. Por supuesto, su solución presumiblemente solo funciona en Linux y otros sistemas Unixish con las/dev
entradas apropiadas , pero raznagul no dijo explícitamente que tenía que funcionar en Windows. Y funciona en TIO.Java, por racer290
Esto fue más bien un olvido básico que los
static
inicializadores son llamados antes delmain
método. Fue un buen intento:throw new Error()
al principio estaba consternado , pero al final encontré el camino;)fuente
System.out.println("Hello World!");
¿No agrega dos enteros? .. " 2. Un fragmento de código que toma dos números como entrada, los suma y genera su suma. Este fragmento debe funcionar correctamente incluso después de ejecutar el primer fragmento. Cuando los dos fragmentos son combinados, deben formar un programa completo que agregue dos números, o definir una función que agregue dos números. Este fragmento probablemente dependerá de un comportamiento oscuro y será difícil de encontrar. "Java por Kevin Cruijssen
Bien construido Una gran cantidad de código para que cualquiera reflexione adecuadamente sobre cómo resolver este desafío. Supongo que "poner su código después" fue una gran, gran pista.
Pruébalo aquí.
fuente
JavaScript de Grant Davis
Funciona en la consola JS en la
about:blank
página (como se especifica en la publicación de la policía) en Chromium 59 / Linux.fuente
cQuents , Step Hen , 3 bytes
Pruébalo en línea!
Hablé mucho con Step Hen para descubrir cómo demonios funciona su lenguaje extraño, pero en resumen:
Su código fue
#|1,1:A
.#|1,1
es la entrada predeterminada, lo que significa que cualquier entrada dada al programa se agrega con 2 1's. (IE si pasa un 47 y un 53, su entrada es[47, 53, 1, 1]
.:
simplemente establece el modo, que generará eln
elemento th en la secuencia sin
está configurado, y de lo contrario generará la secuencia completa.Finalmente
A
obtiene la primera entrada.Debido a que tenemos 4 entradas
[47, 53, 1, 1]
, agregarBC
al final también obtendría la 2da y 3ra entrada, y la 4ta entrada se convierte implícitamenten
.Debido a que nuestra secuencia es
ABC
, se analiza algebraicamente, lo que significa que se convierte enA*B*C
. No queremos eso, pero si insertamos a+
entre A y B, se convierte enA+B*C
, dondeA
yB
son nuestras entradas, yC
es 1.fuente
how the hell his weird language works
tal vez una vez que lo termine, podría tener más sentidoC # (.NET Core) por raznagul
Pruébalo en línea!
Probablemente esto hubiera tomado menos tiempo si realmente conociera C #. Sin embargo, con un poco de exploración de la documentación y un poco de ayuda de Jon Skeet , logré improvisar algo que funciona.
fuente
Vim Challenge por @DJMcMayhem
Ha pasado un tiempo desde que no pude salir de vim , aquí está mi solución (tenga en cuenta que es mucho más que
23
bytes, por lo que probablemente no sea la solución deseada):Pruébalo en línea!
La idea es simplemente tubo de los dos números enteros a
awk
travésbash
, ya que=
y+
eran discapacitados tuve que usar un pequeño trabajo en torno. Laawk
línea se expande a:Editar : La intención original era que la entrada ya está en el búfer, pero eso no sería más difícil: la principal dificultad era hacer que la suma funcionara.
Aquí está la solución sugerida por @DJMcMayhem: ¡ Pruébelo en línea!
fuente
[insert your number here]
en modo de inserción. En cambio, ya está en el búfer. Pero podrías evitar esoOecho "<esc>Go"|awk...
, así que creo que esto cuenta. ¡Bien hecho! Este no es el crack que tenía en mente (esperaba una respuesta vim pura), así que probablemente publicaré una nueva respuesta que parchee comandos externos y!
.Java 7 por Poke
Pruébalo en línea!
No se necesitan trucos específicos de Linux, solo un simple enmascaramiento de los nombres no calificados
String
y deSystem
clase. Probablemente esta no sea la solución prevista, pero funciona.fuente
GolfScript por Ilmari Karonen
Pruébalo en línea!
fuente
RProgN2 por @ATaco
Pruébalo en línea!
Esta no es la mejor respuesta que podría haber dado, pero permite sumar números nuevamente. Si realmente lo hubiera hecho e hice un manejo adecuado de la pila, probablemente podría jugar golf bastante, pero a partir de ahora estoy contento con la respuesta.
En la publicación original de ATaco, efectivamente reasignó todos los operadores aritméticos principales para destruir sus entradas. Para solucionar este problema, redefiní qué adición era en términos de sus operaciones binarias, lo cual fue un dolor porque RProgN2 no tiene un operador de negación binaria o xor.
Nota: Si desea probar la entrada, los números con más de un dígito deben tener la forma
"XX..." n
para convertirse en un número real, ya que RProgN2 toma cada carácter tal cual, a menos que sea un concepto o una cadena. Editar: @ATaco señaló que agregar un '$' antes de un número de varios dígitos hará lo mismo.EDITAR: Aquí está la lógica de mi solución. Como puede ver, definitivamente no es el código más refinado, pero funciona.
fuente
56$46$12
, empujará los números 5, 6, 46 y 12. Publicaré mi solución real y tal mañanaJavaScript (Node.js) por jrich , 298 bytes
Siento que esta no es la solución prevista, pero si lo es, bien hecho, ¡pasé un tiempo tratando de descubrir cómo obtener el nombre de la función declarada! :)
Pruébalo en línea!
fuente