Haskell , 306 + 624 = 930 Bytes
Programm 1: Eine anonyme Funktion, die ein Dummy-Argument verwendet und eine Zeichenfolge zurückgibt.
(\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))"
Probieren Sie es online!
Programm 2: q[[40,...]]
Am Ende steht eine anonyme Funktion, die ein Dummy-Argument verwendet und einen String zurückgibt.
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]]
Probieren Sie es online!
Zeichensatz 1 (einschließlich Leerzeichen):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Zeichensatz 2 (einschließlich Zeilenvorschub):
!'+,.0123456789<=@[]_qxz~
Da nur Satz 1 Nicht-ASCII-Zeichen enthält, sind ihre UTF-8-Bytes auch nicht verbunden.
Wie es funktioniert
Programm 1 wird im Allgemeinen mit Lambda-Ausdrücken, Leerzeichen und Klammern, der freien Verwendung integrierter alphanumerischer Funktionen und den Quine-Daten als String-Literale am Ende geschrieben.
- Der Kerncode von Programm 1 wird einfach durch Umgeben mit Anführungszeichen in Zeichenfolgenliteraldaten umgewandelt.
- Um dies zu unterstützen, folgt jedem Backslash
a
oder b
, die gültige Escape-Sequenzen bilden, die durchlaufen show
.
- Ein weiterer Vorteil ist , dass winzige
a
, b
und c
sind die einzigen Kleinbuchstaben , deren ASCII - Codes sind weniger als 100, eine Ziffer in der numerischen Codierung von Programm 2 verwendet zu speichern.
- Die String-Literal-Codierung des Kerncodes von Programm 2 wird durch die Verwendung von Nicht-ASCII-Unicode verschleiert: Zu jedem Zeichen wird ein Code-Punkt hinzugefügt, um sicherzustellen, dass es keine Überschneidungen mit den Originalzeichen gibt.
- 182 war früher 128, bis mir klar wurde, dass ich die Tatsache missbrauchen könnte, dass 182 doppelt so lang ist wie das String-Literal für den Code von Programm 1, um die Dekodierung zu verkürzen. (Als Bonus kann Programm 2 Zeilenumbrüche verwenden.)
Programm 2 wird im Allgemeinen mit Funktionsgleichungen der obersten Ebene (mit Ausnahme der letzten anonymen), Zeichenliteralen und Dezimalzahlen, Listen- / Bereichssyntax und Operatoren sowie den Quinedaten als Liste von Listen mit Int
s am Ende geschrieben.
- Der Kerncode von Programm 1 wird als Liste seiner Codepunkte mit einem abschließenden doppelten Anführungszeichen codiert.
- Der Kerncode von Programm 2 wird als die Liste der Codepunkte des in Programm 1 verwendeten Zeichenfolgenliteral codiert, das immer noch um 182 nach oben verschoben ist.
Exemplarische Vorgehensweise, Programm 1
b
und c
sind die Werte der String-Literale für Programm 2 bzw. 1, die als letzte Argumente für den Lambda-Ausdruck angegeben werden. ()
ist ein Scheinargument, das ausschließlich der PPCG-Regel entspricht, dass das Programm eine Funktion definieren soll.
foldr(\a->map pred)b(show()>>c)
Dekodiert die Zeichenfolge b
in den Kerncode von Programm 2, indem sie map pred
so oft angewendet wird, wie es der Länge von show()>>c == c++c
oder entspricht 182
.
tail(show c)
konvertiert die Zeichenfolge c
in den Kerncode von Programm 1, wobei ein abschließendes Anführungszeichen angehängt wird.
:pure b
kombiniert dies in einer Liste mit der Zeichenfolge b
.
map(map fromEnum)$
konvertiert die Zeichenfolgen in Listen mit Codepunkten.
`mappend`show(...)
serialisiert die resultierende Liste der Listen und hängt sie schließlich an den Kerncode von Programm 2 an.
Exemplarische Vorgehensweise, Programm 2
- Die oberste Ebene
z~z=[[['@','0'..]!!4..]!!z]
ist eine Funktion, die Codepunkte zurück in Zeichen konvertiert (zum Schreiben erforderlich, da nicht alle Zeichen in toEnum
verfügbar sind.)
- Sein Codepunktargument wird auch aufgerufen
z
. Der Laziness-Marker ~
hat in dieser Position keine Auswirkung, vermeidet jedoch ein Leerzeichen.
['@','0'..]
ist ein Rückwärtsschrittlistenbereich, der mit dem ASCII-Code 64 beginnt und bei jedem Schritt um 16 nach unten springt.
- Wenn
!!4
man sich darauf bezieht , erhält man einen \NUL
Charakter.
- Wenn Sie das in einen
[ ..]
Bereich einschließen, erhalten Sie eine Liste aller Zeichen, die !!z
indiziert werden.
- Das Zeichen wird schließlich in eine Singleton-Liste eingeschlossen. Dies ermöglicht das Zuordnen der Funktion
z
über Listen unter Verwendung =<<
der nicht verfügbaren map
und <$>
.
- Die oberste Ebene
q[x,q]_=z=<<x++q++[34,34]++x
ist ein Funktionskonstruktionsprogramm 1 aus der Quinedatenliste.
x
sind die Daten für den Kern von Programm 1 (einschließlich eines abschließenden doppelten Anführungszeichens) und die inneren q
sind die verschleierten Daten für den Kern von Programm 2. _
ist ein weiteres Scheinargument, das ausschließlich dazu dient, die abschließende anonyme Funktion zu einer Funktion statt nur einer Zeichenfolge zu machen.
x++q++[34,34]++x
Verkettet die Teile, einschließlich zweier doppelter Anführungszeichen mit ASCII-Code 34.
z=<<
Erstellt Programm 1 durch Mapping z
über die Verkettung, um von Codepunkten in Zeichen zu konvertieren.
- Das Finale
q[[40,...]]
ist eine anonyme Funktion, die q
mit den Quine-Daten kombiniert wird .