Haskell , 306 + 624 = 930 octets
Programme 1: une fonction anonyme prenant un argument fictif et renvoyant une chaîne.
(\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))"
Essayez-le en ligne!
Programme 2: q[[40,...]]
à la fin est une fonction anonyme prenant un argument fictif et renvoyant une chaîne.
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]]
Essayez-le en ligne!
Jeu de caractères 1 (inclut l'espace):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Jeu de caractères 2 (inclut la nouvelle ligne):
!'+,.0123456789<=@[]_qxz~
Étant donné que seul l'ensemble 1 contient des caractères non ASCII, leurs octets UTF-8 sont également disjoints.
Comment ça marche
Le programme 1 est généralement écrit avec des expressions lambda, des espaces et des parenthèses, une utilisation gratuite des fonctions alphanumériques intégrées et avec les données de quine en tant que littéraux de chaîne à la fin.
- Le code principal du programme 1 est transformé en données littérales de chaîne simplement en l'entourant de guillemets.
- Pour prendre en charge cela, chaque barre oblique inverse est suivie de
a
ou b
, qui forment des séquences d'échappement valides qui font le tour show
.
- Un autre avantage minuscule est que
a
, b
et c
sont les seules lettres minuscules dont les codes ASCII sont inférieurs à 100, enregistrant un chiffre dans le codage numérique utilisé par le programme 2.
- Le codage littéral de chaîne du code principal du programme 2 est plus obscurci en utilisant Unicode non ASCII: Chaque caractère a 182 ajoutés à son point de code pour assurer qu'il n'y a pas de chevauchement avec les caractères originaux.
- 182 était auparavant 128, jusqu'à ce que je réalise que je pouvais abuser du fait que 182 est deux fois la longueur du littéral de chaîne pour le code du programme 1 pour raccourcir le décodage. (En prime, le programme 2 peut utiliser des sauts de ligne.)
Le programme 2 est généralement écrit avec des équations de fonction de niveau supérieur (à l'exception de la dernière anonyme), des littéraux de caractères et des nombres décimaux, une syntaxe de liste / plage et des opérateurs, et avec les données de quine comme une liste de listes de Int
s à la fin.
- Le code principal du programme 1 est codé sous la forme d'une liste de ses points de code, avec une citation finale.
- Le code principal du programme 2 est codé comme la liste des points de code du littéral de chaîne utilisé dans le programme 1, toujours décalé vers le haut de 182.
Procédure pas à pas, programme 1
b
et c
sont les valeurs des littéraux de chaîne pour le programme 2 et 1, respectivement, données comme arguments finaux à l'expression lambda. ()
est un argument factice uniquement pour satisfaire la règle de PPCG selon laquelle le programme doit définir une fonction.
foldr(\a->map pred)b(show()>>c)
décode la chaîne b
en code de base du programme 2 en lui appliquant map pred
un nombre de fois égal à la longueur de show()>>c == c++c
, ou 182
.
tail(show c)
convertit la chaîne c
en code de base du programme 1, avec un guillemet double final ajouté.
:pure b
combine cela dans une liste avec la chaîne b
.
map(map fromEnum)$
convertit les chaînes en listes de points de code.
`mappend`show(...)
sérialise la liste de listes résultante et l'ajoute finalement au code principal du programme 2.
Procédure pas à pas, programme 2
- Le niveau supérieur
z~z=[[['@','0'..]!!4..]!!z]
est une fonction qui convertit les points de code en caractères (nécessaire pour écrire car tous les caractères ne toEnum
sont pas disponibles.)
- Son argument de point de code est également appelé
z
. Le marqueur de paresse ~
n'a aucun effet dans cette position mais évite un caractère d'espace.
['@','0'..]
est une plage de liste de pas en arrière commençant par le code ASCII 64, puis sautant 16 vers le bas à chaque étape.
- S'appliquer
!!4
à cela donne un \NUL
caractère.
- Envelopper cela dans une
[ ..]
plage donne une liste de tous les caractères, qui !!z
indexe.
- Le personnage est finalement enveloppé dans une liste singleton. Cela permet de mapper la fonction
z
sur des listes en utilisant =<<
au lieu de l'indisponible map
et <$>
.
- Le niveau supérieur
q[x,q]_=z=<<x++q++[34,34]++x
est une fonction construisant le programme 1 à partir de la liste des données de quine.
x
est les données pour le noyau du programme 1 (y compris une double citation finale) et l'intérieur q
est les données obscurcies pour le noyau du programme 2. _
est un autre argument factice uniquement pour faire de la fonction anonyme finale une fonction au lieu d'une simple chaîne.
x++q++[34,34]++x
concatène les pièces, y compris deux guillemets doubles avec le code ASCII 34.
z=<<
construit le programme 1 en mappant z
sur la concaténation pour convertir des points de code en caractères.
- La finale
q[[40,...]]
est une fonction anonyme se combinant q
avec les données de quine.