Haskell , 306 + 624 = 930 bytes
Programa 1: una función anónima que toma un argumento ficticio y devuelve una cadena.
(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"İĴİóđđđÝöÝâÝæÝääē××êääē××İēÀħđĮâħēĕóİóòòĮááħááđéêâéêēááĮÀħ""(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"
Pruébalo en línea!
Programa 2: q[[40,...]]al final es una función anónima que toma un argumento ficticio y devuelve una cadena.
z~z=[[['@','0'..]!!4..]!!z]
q[x,q]_=z=<<x++q++[34,34]++x
q[[40,92,98,32,99,40,41,45,62,102,111,108,100,114,40,92,97,45,62,109,97,112,32,112,114,101,100,41,98,40,115,104,111,119,40,41,62,62,99,41,96,109,97,112,112,101,110,100,96,115,104,111,119,40,109,97,112,40,109,97,112,32,102,114,111,109,69,110,117,109,41,36,116,97,105,108,40,115,104,111,119,32,99,41,58,112,117,114,101,32,98,41,41,34],[304,308,304,243,273,273,273,221,246,221,226,221,230,221,228,228,275,215,215,234,228,228,275,215,215,304,275,192,295,273,302,226,295,275,277,243,304,243,242,242,302,225,225,295,225,225,273,233,234,226,233,234,275,225,225,302,192,295]]
Pruébalo en línea!
Conjunto de caracteres 1 (incluye espacio):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Conjunto de caracteres 2 (incluye nueva línea):
!'+,.0123456789<=@[]_qxz~
Como solo el conjunto 1 contiene caracteres no ASCII, sus bytes UTF-8 también son disjuntos.
Cómo funciona
El programa 1 generalmente se escribe con expresiones lambda, espacios y paréntesis, uso libre de funciones alfanuméricas integradas y con los datos de quine como literales de cadena al final.
- El propio código central del Programa 1 se convierte en datos literales de cadena simplemente rodeándolo con comillas.
- Para respaldar esto, cada barra invertida va seguida de
ao b, que forman secuencias de escape válidas que se realizan de manera circular show.
- Otro pequeño beneficio es que
a, by cson las únicas letras minúsculas cuyos códigos ASCII son inferiores a 100, ahorrando un dígito en la codificación numérica utilizada por el programa 2.
- La codificación literal de cadena del código central del programa 2 está más ofuscada al usar Unicode no ASCII: cada carácter tiene 182 agregados a su punto de código para garantizar que no haya superposición con los caracteres originales.
- 182 solía ser 128, hasta que me di cuenta de que podía abusar del hecho de que 182 es el doble de la longitud del literal de cadena para que el código del programa 1 acorte la decodificación. (Como beneficio adicional, el programa 2 puede usar nuevas líneas).
El programa 2 generalmente se escribe con ecuaciones de función de nivel superior (excepto la anónima final), literales de caracteres y números decimales, sintaxis de lista / rango y operadores, y con los datos de quine como una lista de listas de Ints al final.
- El código central del Programa 1 está codificado como una lista de sus puntos de código, con una doble comilla final.
- El código central del programa 2 está codificado como la lista de puntos de código del literal de cadena utilizado en el programa 1, aún desplazado hacia arriba por 182.
Tutorial, programa 1
by cson los valores de los literales de cadena para el programa 2 y 1, respectivamente, dados como argumentos finales a la expresión lambda. ()es un argumento ficticio únicamente para satisfacer la regla de PPCG de que el programa debe definir una función.
foldr(\a->map pred)b(show()>>c)decodifica la cadena bal código central del programa 2 aplicándolo map predvarias veces igual a la longitud de show()>>c == c++c, o 182.
tail(show c)convierte la cadena cal código central del programa 1, con una doble comilla final añadida.
:pure bcombina esto en una lista con la cadena b.
map(map fromEnum)$ Convierte las cadenas en listas de puntos de código.
`mappend`show(...) serializa la lista de listas resultante y finalmente la agrega al código central del programa 2.
Tutorial, programa 2
- El nivel superior
z~z=[[['@','0'..]!!4..]!!z]es una función que convierte los puntos de código en caracteres (necesarios para escribir, ya que no todos los caracteres toEnumestán disponibles).
- Su argumento de punto de código también se llama
z. El marcador de pereza ~no tiene efecto en esta posición, pero evita un carácter de espacio.
['@','0'..] es un rango de lista de pasos hacia atrás que comienza en el código ASCII 64, y luego salta 16 en cada paso
- Aplicar
!!4esto da un \NULcarácter.
- Ajustar eso en un
[ ..]rango proporciona una lista de todos los caracteres, que !!zindexa.
- El personaje finalmente se envuelve en una lista singleton. Esto permite mapear la función
zsobre listas usando en =<<lugar de las no disponibles mapy <$>.
- El nivel superior
q[x,q]_=z=<<x++q++[34,34]++xes una función que construye el programa 1 de la lista de datos de quine.
xson los datos para el núcleo del programa 1 (incluida una comilla doble final) y el interno qson los datos ofuscados para el núcleo del programa 2. _es otro argumento ficticio únicamente para hacer que la función anónima final sea una función en lugar de solo una cadena.
x++q++[34,34]++x concatena las piezas, incluidas dos comillas dobles con código ASCII 34.
z=<<construye el programa 1 mapeando zsobre la concatenación para convertir de puntos de código a caracteres.
- La final
q[[40,...]]es una función anónima que se combina qcon los datos de quine.