Hintergrund
Das Computerspiel NetHack stammt aus dem Jahr 1987, bevor die Verwendung von Grafiken in Computerspielen weit verbreitet war. Es gibt viele Monster im Spiel und möglicherweise muss eine Menge auf den Bildschirm passen, daher werden Monster auf sehr minimale Weise gezeichnet: Ein Monster wird einfach als ASCII-Zeichen auf dem Bildschirm gezeichnet.
Es gibt nicht nur viele Monster, sondern auch viele Arten von Monstern. Es kann wichtig sein zu wissen, welches welches ist; du müsstest anders reagieren, wenn du ein Kätzchen und einen Drachen siehst. Daher wird der Großteil von ASCII zur Darstellung von Monstern verwendet. Zum Beispiel ist ein Kätzchen f
und ein roter Drache D
. Dies bedeutet, dass es sehr hilfreich sein kann zu wissen, wie ein bestimmtes Monster aussehen wird, da es Ihnen hilft, es zu erkennen, wenn Sie es später im Spiel antreffen. (Beachten Sie, dass es mehr Arten von Monstern gibt als ASCII-Zeichen. Einige von ihnen teilen sich also; ein roter Drache und ein blauer Drache sind beides D
.)
Aufgabe
Ihr Programm muss den Namen eines NetHack-Monsters als Eingabe verwenden und das ASCII-Zeichen erzeugen, das es im Spiel als Ausgabe darstellt. Das Programm darf davon ausgehen, dass es sich bei der Eingabe tatsächlich um den Namen eines NetHack-Monsters handelt. Wenn die Eingabe ungültig ist, kann dies zu Abstürzen, bedeutungslosen Ergebnissen usw. führen.
Das folgende Stack-Snippet ist ein JSON-Objekt, das die vollständige Zuordnung möglicher Eingaben zu den entsprechenden Ausgaben ermöglicht:
Im Grunde genommen lautet die Aufgabe hier "Geben Sie einen Schlüssel im Wörterbuch ein, das vom obigen JSON-Objekt dargestellt wird, und geben Sie den entsprechenden Wert zurück".
Beachten Sie, dass diese Herausforderung in gewisser Weise eine umgekehrte Kolmogorov-Komplexität ist . Anstatt von einer kleinen / leeren Eingabe zu einer großen Ausgabe zu wechseln, wechseln Sie von einer großen Eingabe zu einer kleinen Ausgabe. (Die Eingabe enthält daher viele redundante Informationen, die Sie ignorieren oder nach Belieben verwenden können.) Es ist auch ziemlich ähnlich zu Regex-Golf, außer dass a) jede Sprache erlaubt ist (nicht nur Regex) und b) es mehr als zwei mögliche Ausgaben gibt. (Wir hatten schon einige Aufgaben wie diese, wie diese beiden , aber diese Aufgabe ist etwas anders, weil das angegebene Eingabe- / Ausgabeverhalten stärkere Muster aufweist.)
Klarstellungen
Sie können jedes sinnvolle Eingabe- und Ausgabeformat verwenden (z. B. können Sie die Ausgabe als Zeichen oder als ASCII-Code oder als Zeichenfolge mit einer Länge von einem Zeichen erstellen). Sie können eine Funktion anstelle eines vollständigen Programms einreichen, wenn Sie dies vorziehen.
Dies wird bereits in den Standardlücken erwähnt, aber nur um es noch einmal zu wiederholen: Sie können die Korrespondenz zwischen Eingabe und Ausgabe nur im Quellcode Ihres Programms speichern. Bei dieser Herausforderung geht es im Wesentlichen darum, das Eingabe- / Ausgabeverhalten auf kleinstem Raum darzustellen. Sie dürfen also keine Liste aus dem Internet herunterladen, die Korrespondenz in einer externen Datei speichern, NetHack im Debug-Modus starten und das betreffende Monster erzeugen um zu sehen, wie es aussieht, etc .. (Außerdem möchte ich keine Monster bekämpfen müssen, um deine Beiträge zu testen.)
Siegbedingung
Dies ist Code-Golf , daher ist der gewinnende Eintrag der kürzeste, in Bytes gezählte Eintrag. Viel Glück!
quelle
mail daemon
> _ <Antworten:
Jelly , 309 Bytes in Jellys Codierung
Probieren Sie es online!
Ich entschied, dass es an der Zeit war, meine eigene Herausforderung anzunehmen. Die Verwendung von Jelly (und seiner 8-Bit-Codepage) bietet mir einen Vorteil von 12,5% gegenüber den Nur-ASCII-Sprachen, und Jelly ist für diese Herausforderung geeignet, da es integrierte Operatoren für die Basiskonvertierung mit kurzen Namen hat, aber die meisten Einsparungen erzielt sind auf einen besseren Komprimierungsalgorithmus zurückzuführen (dieses Programm berechnet im Durchschnitt weniger als ein Byte pro Monstertyp).
Algorithmus und Erklärung
Wortbasierte Klassifikation
Ich entschied, dass es für eine gute Punktzahl notwendig war, die Struktur der Eingabe besser auszunutzen als bei anderen Einträgen. Eine Sache , die sehr auffällig ist , dass viele Monster haben Namen der Form „ Adjektiv Spezies “; a
red dragon
und ablue dragon
sind beide Drachentypen und erscheinen daher alsD
. Einige andere Monster haben Namen der Form " Spezies Job ", wie dieorc shaman
; Als eine Art Ork erscheint dies also
. Komplizierende Dinge sind die Untoten; akobold zombie
ist sowohl ein Kobold als auch ein Zombie, und der letztere Status hat Vorrang bei der Benennung von NetHack-Monstern. Daher möchten wir dies als klassifizierenZ
.Als solches habe ich die Wörter, die in Monsternamen vorkommen, wie folgt klassifiziert: Ein Indikator ist ein Wort, das stark auf die entsprechende Monsterklasse
sphere
hinweist (z. B. deutet stark darauf hin, dass das Monster in der Klasse iste
); ein mehrdeutiges wort ist ein wort, das viel weniger suggeriert (lord
nicht viel sagt), und alle anderen wörter sind nicht wörter , die uns egal sind. Die Grundidee ist, dass wir die Wörter im Monsternamen vom Ende bis zum Anfang von hinten betrachten und den ersten Indikator auswählen, den wir sehen. Daher musste sichergestellt werden, dass jeder Monstername mindestens einen Indikator enthielt, auf den ausschließlich mehrdeutige Wörter folgten. Ausnahmsweise Wörter, die in den Namen von Monstern vorkommen, die aussehen wie@
(die größte Gruppe) werden alle als mehrdeutig eingestuft. Vor einem Indikator kann alles stehen. Beispielsweise erscheinen Farbnamen (wiered
) in einem Namen immer früher als ein Indikator und werden daher als Nichtwörter betrachtet (da sie bei der Bestimmung der Identität eines Monsters niemals untersucht werden).Am Ende läuft dieses Programm wie die anderen Programme auf eine Hash-Tabelle hinaus. Die Tabelle enthält jedoch nicht Einträge für alle Monsternamen oder für alle Wörter, die in Monsternamen vorkommen. vielmehr enthält es nur die Indikatoren. Die Hashes mehrdeutiger Wörter erscheinen nicht in der Tabelle, sondern müssen leeren Slots zugewiesen werden (der Versuch, ein mehrdeutiges Wort nachzuschlagen, bleibt immer leer). Bei Nichtwörtern spielt es keine Rolle, ob das Wort in der Tabelle erscheint oder nicht, oder ob der Hash kollidiert oder nicht, da wir niemals den Wert verwenden, ein Nichtwort nachzuschlagen. (Die Tabelle ist ziemlich spärlich, daher werden die meisten Nichtwörter nicht in der Tabelle angezeigt, aber einige, wie z. B.
flesh
, werden als Folge von Hash-Kollisionen in der Tabelle gefunden.)Hier einige Beispiele, wie dieser Teil des Programms funktioniert:
woodchuck
ist ein einzelnes Wort lang (also ein Indikator) und die Tabellensuchewoodchuck
gibt uns die beabsichtigte Antwortr
.abbot
ist auch ein einziges Wort lang, sieht aber aus wie ein@
. Als solchesabbot
wird ein mehrdeutiges Wort betrachtet; Die Tabellensuche ist leer und wir geben@
standardmäßig eine Antwort von zurück.vampire lord
besteht aus einem Indikator (vampire
entsprichtV
) und einem mehrdeutigen Wort (lord
das nicht in der Tabelle enthalten ist). Das heißt, wir überprüfen beide Wörter (in umgekehrter Reihenfolge) und geben dann die richtige Antwort vonV
.gelatinous cube
besteht aus einem Nichtwort (gelatinous
entsprichtH
einer Hash-Kollision) und einem Indikator (cube
entsprichtb
). Da wir nur das letzte Wort nehmen, das in der Tabelle gefunden wurde, wird diesb
wie erwartet zurückgegeben.gnome mummy
besteht aus zwei Indikatoren,gnome
entsprechendG
undmummy
entsprechendM
. Wir nehmen den letzten Indikator und erhaltenM
, was wir wollen.Der Code zum Behandeln der wortbasierten Klassifizierung ist die letzte Zeile des Jelly-Programms. So funktioniert das:
Es gibt zwei reale Fälle; Wenn die Eingabe vollständig aus mehrdeutigen Wörtern besteht, wird
t0
die gesamte Ausgabe der Tabellensuche gelöscht, und es@
wird standardmäßig ein Ergebnis erhalten. Wenn Indikatoren in der Eingabe vorhanden sind,t0
werden alle Elemente rechts vom Indikator ganz rechts gelöscht undṪ
das entsprechende Ergebnis für diesen Indikator ausgegeben.Tabellenkomprimierung
Natürlich löst das Aufteilen der Eingabe in Wörter das Problem nicht von selbst; Wir müssen immer noch die Korrespondenz zwischen Indikatoren und den entsprechenden Monsterklassen codieren (und die fehlende Korrespondenz von mehrdeutigen Wörtern). Dazu habe ich eine spärliche Tabelle mit 181 Einträgen (entsprechend den 181 Indikatoren; dies ist eine große Verbesserung gegenüber den 378 Monstern!) Und 966 Gesamteinträgen (entsprechend den 966 Ausgabewerten der Hash-Funktion) erstellt. Die Tabelle wird im Programm mit zwei Zeichenketten codiert: Die erste Zeichenkette gibt die Größe der "Lücken" in der Tabelle an (die keine Einträge enthalten); und die zweite Zeichenfolge gibt die Monsterklasse an, die jedem Eintrag entspricht. Beides wird übersichtlich über die Basisumsetzung dargestellt.
Im Jelly-Programm wird der Code für die Tabellensuche zusammen mit dem Programm selbst von Anfang
µ
an in der zweiten Zeile dargestellt . So funktioniert dieser Teil des Programms:Die bijektive Basis 21 ist wie die Basis 21, mit der Ausnahme, dass 21 eine gültige Ziffer ist und 0 nicht. Dies ist für uns eine bequemere Codierung, da wir zwei benachbarte Einträge mit einer Lücke von 1 zählen, sodass wir die gültigen Indizes über die kumulative Summe finden können. Wenn es um den Teil der Tabelle geht, der die Werte enthält, haben wir 58 eindeutige Werte, also dekodieren wir zuerst in 58 aufeinanderfolgende ganze Zahlen und dekodieren dann erneut mit einer Nachschlagetabelle, die diese den tatsächlich verwendeten Zeichen zuordnet. (Die meisten davon sind Buchstaben, also beginnen wir diese sekundäre Nachschlagetabelle mit den Nicht-Buchstaben-Einträgen
&;:'
und hängen dann einfach eine Jelly-Konstante an, die mit den Groß- und Kleinbuchstaben beginnt. Sie enthält auch einen anderen Müll, der uns aber egal ist über das.)Wenn Sie den Sentinel-Wert "index not found" von Jelly zum Indizieren in eine Liste verwenden, wird das letzte Element der Liste zurückgegeben. Daher habe ich der Nachschlagetabelle eine Null angehängt (eine ganzzahlige Null, auch wenn die Tabelle hauptsächlich aus Zeichen besteht), um ein passenderes Sentinel anzugeben, das auf einen fehlenden Eintrag hinweist.
Hash-Funktion
Der verbleibende Teil des Programms ist die Hash-Funktion. Das fängt einfach genug an, mit
OḌ
; Dies konvertiert die Eingabezeichenfolge in ihre ASCII - Codes und berechnet dann den letzten Code plus den 10 - fachen vorletzten Code plus den 100 - fachen Code zuvor und so weiter String → Integer-Konvertierungsfunktion). Wenn wir diesen Hash jedoch einfach direkt über eine Modul-Operation reduzieren würden, bräuchten wir eine ziemlich große Tabelle. Stattdessen beginne ich mit einer Operationskette, um die Tabelle zu verkleinern. Sie arbeiten jeweils folgendermaßen: Wir nehmen die fünfte Potenz des aktuellen Hashwerts; dann reduzieren wir den Wert modulo um eine Konstante (welche Konstante von der von uns verwendeten Operation abhängt). Diese Kette bietet auf zwei Arten mehr Einsparungen (in Bezug auf die Reduzierung der resultierenden Tabellengröße) als Kosten (in Bezug auf die Notwendigkeit, die Operationskette selbst zu codieren): Sie kann die Tabelle erstellenviel kleiner (966 statt 3529 Einträge), und die Verwendung mehrerer Stufen bietet mehr Gelegenheit, nützliche Kollisionen einzuführen (dies ist nicht viel passiert, aber es gibt eine solche Kollision: sowohlDeath
als auchYeenoghu
Hash auf 806, wodurch wir eine entfernen können Eintrag vom Tisch, als sie beide gehen&
). Die hier verwendeten Module sind [3529, 2163, 1999, 1739, 1523, 1378, 1246, 1223, 1145, 966]. Im Übrigen liegt der Grund für die Erhöhung auf die fünfte Potenz darin, dass die Lücken in der Regel gleich groß bleiben, wenn Sie den Wert direkt eingeben, während die Exponentiation die Lücken verschiebt und eine gleichmäßigere Verteilung des Tisches nach dem bewirkt Kette statt in einem lokalen Minimum stecken zu bleiben (gleichmäßig verteilte Lücken ermöglichen eine engere Kodierung der Lückengrößen). Dies muss eine ungerade Potenz sein, um zu verhindern, dass x² = (- x )² Kollisionen einführt und 5 besser als 3 funktioniert.Die erste Zeile des Programms codiert die Folge von Modulen mit Delta-Codierung:
Der Rest des Programms, der Beginn der zweiten Zeile, implementiert die Hash-Funktion:
Nachprüfung
Dies ist das Perl-Skript, mit dem ich überprüft habe, ob das Programm ordnungsgemäß funktioniert:
quelle
JavaScript (ES6),
915...902890 BytesFormatiert
Unten finden Sie eine formatierte Version des Codes mit abgeschnittenen Nutzdaten.
Wie es funktioniert
Schritt 1
Wir reduzieren zuerst den Monsternamen um:
1
's.Beispiele:
Dies führt zu einigen Kollisionen. Zum Beispiel
"Master Assassin"
und"Master Kaen"
sind beide auf reduziert"Mst1n"
. Glücklicherweise haben alle Namen kollidierender Monster dasselbe Symbol (@
in diesem Fall).Schritt 2
Dann interpretieren wir diese 5-stellige Zeichenfolge als Basisgröße, um sie in eine Dezimalzahl umzuwandeln (bei dieser Operation wird die Groß- und Kleinschreibung nicht berücksichtigt), und wenden ein Modulo an
8713
, das empirisch ausgewählt wurde, um eine kollisionsfreie Liste von Schlüsseln zu erstellen.Beispiele:
Schritt 3
Alle Schlüssel sind in aufsteigender Reihenfolge sortiert:
Umgerechnet in Delta-Werte:
Und als ASCII-Zeichen im Bereich codiert
[ 32, 126 ]
. Einige Dummy-Zwischenwerte werden eingefügt, wenn die Differenz zwischen zwei aufeinanderfolgenden Tasten die maximal codierbare Größe überschreitet.Schließlich wird die Liste der Tasten einer Liste von Symbolen zugeordnet, die in derselben Reihenfolge angeordnet sind.
Prüfung
Code-Snippet anzeigen
quelle
Java, 1130 Bytes
Ungolfed:
Monsternamen sind:
hashcode
Methode => 32 BitDas Anzeigezeichen ist mit 6 Bits codiert.
Jedes Tupel (Monstername, Charakter) verwendet also 14 Bits. Alle Tupel werden in einem BitSet gespeichert und mit der Basis 64 codiert.
Ich verliere eine Menge Bytes mit Base64-Codierung und BitSet-Operationen :-)
quelle
()->{...}
. Die Frage sagt dies in ihrem Abschnitt "Erläuterungen".Mathematica, 1067 Byte (römische Mac OS-Zeichencodierung)
Unbenannte Funktion, die eine Zeichenfolge als Eingabe verwendet und ein Zeichen zurückgibt. Die Funktion hat folgende Form:
Hier ist GIANT_STRING_1 eine Zeichenfolge mit 608 Ein-Byte-Zeichen in der lateinischen Mac OS-Zeichencodierung (von denen keines im Bereich von 00-1F liegt), während GIANT_STRING_2 eine Zeichenfolge mit 304 ASCII-Zeichen ist.
Zeile 2 startet die Hash-Funktion: Sie konvertiert die Eingabezeichenfolge in eine Liste von Zeichencodes (Codierung irrelevant, da sie alle druckbares ASCII sind) und berechnet dann die Summe dieser Zeichencodes und die Summe ihrer Quadrate, sowohl modulo 216 als auch forcing Die Antwort liegt zwischen 32 und 255. Dann konvertieren die Zeilen 1 und 3 diese geordneten Paare von Ganzzahlen in Zeichenfolgen mit zwei Zeichen. Dies ist der Hash-Wert, den wir letztendlich verwenden.
Zeile 5 verwandelt GIANT_STRING_1 in eine Liste von 304 Zeichenfolgen mit zwei Zeichen. Zeile 6 verwandelt GIANT_STRING_2 in eine Liste von 304 Ein-Zeichen-Strings. Dann wandeln die Zeilen 4 und 5 diese beiden Listen in einen Satz von 304 Ersetzungsregeln um: Wenn Sie eine solche und eine solche Zeichenfolge sehen, wandeln Sie sie in eine solche und eine solche Zeichenfolge um. Schließlich verwandelt Zeile 8 jede verbleibende zweistellige Zeichenfolge in
"@"
.Es gibt 71 Monster in der Liste, deren Symbol ist
"@"
, und diese werden ohne Hash behandelt (ich habe diese Idee aus einem Kommentar von ais523 zu einer anderen Antwort gestohlen). Es ist nur so, dass die anderen 304 Hash-Werte alle eindeutig sind! Daher sind keine weiteren Änderungen am Algorithmus erforderlich. (Es ist ein Glücksfall,"human"
auf den abgebildet werden muss"@"
, da die Summen der Zeichencodes der Buchstaben in"human"
und der Buchstaben in"shark"
identisch sind, ebenso wie die Summen der Quadrate dieser Codes - als ganze Zahlen, nicht einmal modulo 216!)quelle
Python, 2055 Bytes
Hier ist mein Testgeschirr, falls es jemand anderem hilft.
Ich habe ein kleines Programm geschrieben, um die verschiedenen Möglichkeiten zum Extrahieren von 4 Zeichen plus der Länge der Zeichenfolge aufzulisten. Mein ursprünglicher Plan war es,
ord()
diese Zeichen zu analysieren und zu einer perfekten Hash-Funktion zusammenzufassen, die Indizes in einer Tabelle mit Ausgaben erzeugt. Also habe ich ein weiteres kleines Programm geschrieben, um all die verschiedenen Arten des Summierens / Multiplizierens / Modulierens dieser 4 Zeichen zusammen aufzuzählen. aber die daraus resultierenden Hash - Funktionen gehalten, die Art und Weise zu viele Kollisionen. Also habe ich irgendwann aufgegeben und einfach das getan, was Sie hier sehen. Das ist nur eine Karte von der kleinen Darstellung des Monsternamens bis zum entsprechenden Symbol.Das heißt: Was ich bekommen wollte war
aber ich schaffte es nur so weit zu kommen
wo mein Diktat Lookup
{relatively_large_dict}[small_string]
alsre.match(small_string+"(.)", "relatively_large_string")
für Golfiness ausgedrückt wird.quelle
JavaScript (ES6), 1178
Weniger golfen
Prüfung
quelle
Javascript, 1185 Bytes
Verwendet eine Golf-Version des hier gefundenen Javascript-String-Hashs . Der in der Tabelle gespeicherte tatsächliche Hash (diese lange Zeichenfolge) nimmt den Absolutwert des von dieser Methode erzeugten Hashs, konvertiert ihn in base-36 und löscht alle Ziffern mit Ausnahme der drei niedrigstwertigen Ziffern.
quelle
@
aus der Tabelle entfernen und nur die Standardeinstellung für@
die Eingabe verwenden wird nicht gefunden.cavewoman
undchameleon
haben die gleichen ersten Zeichen, letzten Zeichen und Länge, das kann ein Problem sein?split("_")
kannsplit
backtick werden_
backtickCyclops
undCroesus
,baluchitherium
undbaby long worm
,crocodile
undcentipede
, und 24 mehrPython 3,
1915 -1900 BytesÄnderungsprotokoll:
Übergebe den Monsternamen als erstes Kommandozeilenargument und erhalte das Zeichen auf stdout.
Als ich die Frage las, dachte ich "Ich muss das komprimieren". Der erste Schritt bestand darin, alle Namen in Kleinbuchstaben zu schreiben.
Als ich mir die Daten ansah, hatte ich das Gefühl, dass die Verwendung des ersten Buchstabens des letzten Wortes den Trick als grobe erste Vermutung, welche Buchstaben das Monster haben könnte, tun sollte. Wie sich herausstellte, war das eine starke anfängliche Vermutung. Die folgende Tabelle enthält "erstes Zeichen des letzten Wortes", "Anzahl der Treffer" und "Monsterzeichen":
Um die Streuung weiter zu verbessern, habe ich den Schlüssel leicht modifiziert, indem ich das zweite Zeichen des letzten Wortes, das zu Bits nach rechts verschoben ist, in das erste Zeichen XOR-verknüpft habe (nennen wir dieses Konstrukt
first_key
):Wie Sie sehen, erhalten wir neun Namen, die nur mit diesen Informationen eindeutig zugeordnet werden können. Nett!
Jetzt musste ich die verbleibende Zuordnung finden. Zu diesem Zweck habe ich zunächst den vollständigen Namen (in Kleinbuchstaben) in eine Ganzzahl umgewandelt:
Dies verkettet einfach die 7-Bit-ASCII-Werte der Namen zu einer riesigen Ganzzahl. Wir nehmen dieses Modulo
4611686018427387903
(2⁶²-1) für die nächsten Schritte.Jetzt versuche ich, eine Bitmaske zu finden, die eine Ganzzahl ergibt, die wiederum die verschiedenen Monstercharaktere gut unterscheidet. Die Bitmasken bestehen aus gleichmäßig verteilten (wie z. B.
101010101
oder1000100010001
) und werden durch die Anzahl der Bits (i>=1
) und die Spreizung (k>=1
) parametrisiert . Außerdem werden die Masken um bis zu32*i
Bits nach links verschoben . Diese werden mit dem ganzzahligen Namen UND-verknüpft und die resultierende Ganzzahl wird als Schlüssel in einem Mapping verwendet. Die beste (durchi*number_of_mapping_entries
) konfliktfreie Zuordnung wird verwendet.Die ganzen Zahlen , die aus AND-ing der Maske und des integerised Namen verschoben zurück von
j
Bits und gestrippt ihrer Nullen (wir speicherni
,k
undj
zusammen mit der Zuordnung der Lage sein , das zu rekonstruieren), viel Platz zu sparen.Jetzt haben wir also eine zweistufige Zuordnung: Von
first_key
zur Hashmap, und die Hashmap ordnet den vollständigen Namen dem Monstercharakter eindeutig zu. Wir müssen das irgendwie speichern. Jeder Eintrag des Top-Level-Mappings sieht folgendermaßen aus:gefolgt von den Monster-Charakteren und dem Mapping der zweiten Ebene.
Die Zuordnung der zweiten Ebene wird serialisiert, indem sie in eine große Ganzzahl gepackt und in Bytes konvertiert wird. Jeder Wert und jeder Schlüssel wird nacheinander in die Ganzzahl verschoben, wodurch die Zuordnung rekonstruierbar wird (die Anzahl der Bits pro Schlüssel / Wert ist aus der Anzahl der Zeichen ableitbar und
i
beide im Zeileneintrag gespeichert).Wenn ein Eintrag nur ein einziges mögliches Monsterzeichen enthält, auf das eine Zuordnung erfolgen kann,
i
ist der Wert Null, und die Anzahl der Zeichen und die Zuordnung sind ebenfalls null Byte. Das Zeichen wird dort gespeichert, woj
es normalerweise gespeichert werden würde.Die vollständigen Daten haben eine Größe von 651 Byte und sind als Python-Byte-Zeichenfolge mit 1426 Byte serialisiert.
Das Dekodierungsprogramm macht es im Wesentlichen umgekehrt: Zuerst extrahiert es
first_key
die Daten und sucht in den Daten nach dem entsprechenden Eintrag. Dann berechnet es den Hash des Namens und durchsucht die Hashmap nach dem entsprechenden Eintrag.Unverdeckter Decoder
Analyse-Tool
Dies ist das Tool, das ich erstellt und verwendet habe, um die Daten zu generieren - lesen Sie auf eigenes Risiko:
Testfahrer
quelle
awk 73 + 2060 bytes
Die Daten wurden dazu aufbereitet:
(2060 Zeichen) dh. zu kürzester eindeutiger Zeichenfolge mit dem an den Namen angehängten Monsterzeichen und schließlich zu dieser Form:
(Am Anfang der Zeichenfolge muss ein Fallback-Zeichen stehen, um eine Nichtübereinstimmung zu kennzeichnen.) Bei der Suche nach einer Übereinstimmung wird der Name vom Ende an durch das Zeichen gekürzt, bis eine Übereinstimmung vorliegt, und das nächste Zeichen nach der Übereinstimmung wird zurückgegeben :
Ich kann immer noch ein paar Bytes von der Monsterschnur entfernen, wenn ich etwas organisiere:
Wenn man bedenkt, wie groß die Daten mit Monsternamen sind, die mit
A
38 Bytes beginnen, bedeutet dies, dass die Datengröße im Durchschnitt von 2060 auf 1193 gesunken ist.Dies ist noch in Arbeit und der Monster-String wird etwas später veröffentlicht.
quelle