Rebmu : 79 caracteres O (37 + longitud (p1) + 2 * max (longitud (p2), longitud (p3)))
Primero daré una solución de 79 caracteres que pregunta ¿Qué idiomas debes aprender? (entropía 4.0, 30 letras no incluidas ?
) y le ofrece las sugerencias de Rebol y [Rojo] :
DD 11 DD :do dd {dd {p{Which languages must you learn?}qt}} pp{{[RReebdo]l}}
Una táctica única disponible aquí que no está en otros idiomas proviene de aprovechar el hecho de que las llaves son un delimitador de cadenas asimétrico, que puede anidar legalmente:
my-string: {"It's cool," said {Dr. Rebmu}, "for MANY reasons--like less escaping."}
Eso me permite producir una solución generalizada, que puede funcionar sin esfuerzo en cualquier programa que no use secuencias de escape. La versión de 79 caracteres era lo suficientemente simple como para un acceso directo, pero para contener adecuadamente la fuente de programa arbitraria para los programas p2 y p3 necesitaría la plantilla completa. Si hubiéramos usado eso, habrían sido 87 caracteres:
DD 11 DD :do dd {dd {p{Which languages must you learn?}qt}} ddoo{{pp{{[RReebdo]l}}}}
El patrón para utilizar esta forma general es que si tiene tres textos fuente de caracteres secuenciales de longitud variable (Usemos un ejemplo como AAA
, BBBBB
, CCCCCCC
) se puede codificar como algo a lo largo de las líneas de:
DD 11 DD :do dd {dd {AAAqt}} ddoo{{BCBCBCBCBC C C}}
(Nota: aunque este patrón no funcionará sin modificar los programas que usan caracteres de escape, esto no es un defecto fatal. Obtener un paréntesis izquierdo sin igual en una cadena delimitada por llaves requiere algo como {Foo ^{ Bar}
... pero podría reescribirlo fácilmente usando la notación de cadena alternativa "Foo { Bar"
, y los casos combinados se pueden manejar pegando una mezcla de cadenas sin escape).
Entonces ... ¿qué tal un ejemplo? Una vez que el formulario general estuvo disponible, este programa de 573 caracteres se ensambló en solo un par de minutos a partir de 3 soluciones de golf de código anteriores:
DD 11 DD: do dd {dd {rJ N 0% rN Wa1m2j S {\ x /} D00 Hc & [u [Ze? Wa Qs ~ rpKw [isEL00c [skQd2k] [eEV? KQ [tlQ]] pcSeg - b00 [ eZ 1 5] 3] prRJ [si ~ dSPscSqFHs] eZ 1 [s + dCa + wM2cNO]]] Va | [mpAp2j] prSI ~ w { } Ls2w Wl h01tiVsb01n -1 chRVs { } hLceVn01qt}} ddoo {{BrdCz [{BrbCz [ [sn [{N sbeo [tIt0l1eV} 0e5gXN1 01L {5s0} C {1} 0 {0 Do5f0 0bMe1e0r0} 0]]] tMw9C9 Numz Jl [paN + [KperlCJBn [[ba sWS {B noJn Nt0hJl jl jl)] {K, j} b P {. } lf EZ - - n [N m {G otothtoreandbuysome more}] {T akeonedowna and passitar ound} c B w P lf]]}}
Si alguien quiere intentar escribir ese programa en el idioma de su elección y cree que puede vencer a 573, avíseme. Si lo haces, te recompensaré con una gran cantidad de reputación, suponiendo que tu idioma de elección no sea Rebmu, porque sé que esos programas no son mínimos. :-)
Ese espaciado "derrochador" que obtienes al final es lo que sucede cuando p2 y p3 tienen longitudes desequilibradas. Pero los 3 programas son de diferentes tamaños en este caso, por lo que no hay un buen emparejamiento particular para elegir para p2 / p3. (Los elegí porque no había datos externos como entrada, como un laberinto o lo que sea, no es que fueran de longitudes similares. Si bien podría haber escrito nuevos programas que fueran más óptimos, he pasado suficiente tiempo y el punto era usted no tiene que escribir nuevos programas ...)
Cómo funciona
(Nota: comencé con un enfoque más "creativo" que no era tan simple pero de aspecto más interesante. Lo moví a una entrada en mi blog, ya que describir este enfoque ya es largo).
Una clave aquí es el truco de "evaluar el código como una cadena" como algunas otras entradas, solo tiene la carta de triunfo del delimitador de cadena asimétrica. Comenzaré explicando el funcionamiento del caso de 80 caracteres.
Aquí está el programa "completo", ajustando el espacio en blanco para la legibilidad de este caso:
DD 11 ; assign 11 to dd (about to overwrite again)
DD :do ; make dd a synonym for DO (a.k.a. "eval")
; eval a string as source code that ends with QUIT (QT)
dd {dd {p{Which languages must you learn?}qt}}
; we'll never get here, but whatever's here must be legally parseable
pp{{[RReebdo]l}}
Aquí terminamos configurando DD como sinónimo de DO (también conocido como "eval"). Pero el truco es que cuando se ejecutan los programas reducidos a la mitad, terminan ejecutando código cuyo único efecto es definir D en el inofensivo literal 1.
Esto es lo que hace el código de caracteres impares, el espacio en blanco nuevamente ajustado:
D 1 ; assign 1 to d
D d ; assign d to itself, so it's still 1
d ; evaluates to integer, no side effect
{d pWihlnugsms o er?q} ; string literal, no side effect
p {Rebol} ; print "Rebol"
Y aquí está el código de caracteres pares:
D 1 ; assign 1 to d
D:od ; URL-literal (foo:...), no side effect
d ; evaluates to integer, no side effect
{{hc agae utyulan}t} ; string literal (well-formed!), no side effect
p {[Red]} ; print "[Red]"
Es realmente el caso de que para el programa no reducido a la mitad, dd {dd {(arbitrary code)qt}}
ejecutará el código que desee. Sin embargo, hay dos llamadas para evaluar en lugar de solo una. Esto se debe a que, si bien las llaves anidadas funcionan muy bien en el código intercalado, arruinan el comportamiento de evaluación de DO. Porque:
do {{print "Hello"}}
Cargará la cadena como un programa, pero ese programa termina siendo solo la constante de la cadena {print "Hello"}
. Por lo tanto, el truco que uso aquí es tomar mi DD (que tiene el mismo valor de función que DO) y ejecutarlo dos veces. Las mitades mastican las diferentes partes de la cadena, pero no mastican ambas si la par / impar es correcta para el contenido, y porque lo que queda fuera de la cadena después de la mitad es solo la constante integral d
, son inofensivas.
Con este patrón no hay ningún desafío en escribir el comportamiento del programa cuando no se reduce a la mitad: puede poner cualquier cosa siempre que la longitud del código sea uniforme (impar si cuenta el QT, que es QUIT). Si necesita obtener el número par de uno impar, agregue un espacio (por lo que en realidad hay un +1 en mi fórmula anterior en p1 para longitudes impares de programa de p1) . El truco parecería escribir ese código intercalado después, que debe pasar el analizador si no se reduce a la mitad. (No se ejecutará debido al QT, pero debe CARGARSE antes de ejecutarse).
Este caso es trivial; pp
se carga bien como símbolo aunque no esté definido, y se divide en p
para imprimir en cada medio programa. Pero podemos hacer otro truco simplemente usando una cadena literal nuevamente. Los programas a la mitad todavía tienen DO definido normalmente, por lo que también podríamos haber dicho:
ddoo{{pp{{[RReebdo]l}}}}
Al hacer que la única parte recogida por el analizador en todo el caso sea la palabra simbólica ddoo
y un literal de cadena, podemos intercalar cualquiera de los dos programas que deseamos dentro de ese literal de cadena y no enojar al analizador. Las versiones reducidas a la mitad solo dirán:
do{p{Rebol}}
..y...
do{p{[Red]}}
Como digo, esta parte parece familiar a otras soluciones que tratan los programas como cadenas y los evalúan. Pero en el caso de la competencia, cuando los programas que está empaquetando contienen cadenas anidadas, eso les arroja llaves. Aquí, las únicas cosas que lo meterán en problemas son el uso de escapar a través de carets ( ^
) ... que puede solucionarse fácilmente.
(Pequeña nota de 'trampa': agregué QT para "QUIT" en respuesta a este problema. En realidad, había eliminado a propósito la abreviatura para dejar de fumar antes ... porque de alguna manera pensé que solo era bueno para el uso de la consola y simplemente retomando el espacio de dos letras si no estaba en un REPL. Lo agrego porque veo que estaba equivocado, no lo agregué para este caso en particular. Sin embargo, antes de ese cambio, habría sido 2 caracteres más. Además, cuando publiqué la solución por primera vez, había un error en Rebmu que impedía que funcionara aunque debería haberlo hecho ... ahora funciona).
x0=00;;
. ¡Gran reto!