Randall Munroe (Autor von XKCD) führte eine Umfrage durch, um den Farben Namen zu geben . Das Hauptergebnis ist eine Liste mit Namen für die 954 häufigsten RGB-Monitorfarben .
Zur Vereinfachung der Programmierung finden Sie hier die Liste im Klartext: http://xkcd.com/color/rgb.txt . Achtung, die erste Zeile enthält keine Daten, sondern die Lizenz.
Schreiben Sie ein Programm oder eine Funktion, die einen gültigen Farbnamen aus der obigen Liste als Eingabe verwendet und den zugehörigen RGB-Farbcode ausgibt. Ihr Programm muss ungültige Eingaben in keiner definierten Weise verarbeiten.
Es gelten Standardlücken. Darüber hinaus darf Ihre Antwort keine vordefinierten (integrierten oder externen) Farbcode- <-> Farbnamenskarten verwenden. (Dies schließt die verknüpfte Liste ein.) Der kürzeste Code in Bytes gewinnt. Wenn Sie aus einer Datei lesen, muss die Byteanzahl der Datei angegeben werden.
Beispiele:
dark peach -> #de7e5d
robin's egg blue -> #98eff9
pink/purple -> #ef1de7
shit #7f5f00
-bubble gum pink #ff69af
,bubblegum pink #fe83cc
Antworten:
Perl 5 -
421239563930407 Bytes für den Code und 3523 für die Datendatei. Binärdaten werden aus der Datei 'g' gelesen, von der sich hier ein Hexdump befindet .
Hierbei wird eine perfekte Hash-Funktion verwendet, die mit GNU gperf generiert wurde. Dabei wird jedem Farbnamen eine eindeutige Ganzzahl im Bereich von 0 bis 6304 zugewiesen , mit der eine Tabelle indiziert werden kann. Die gezippten Daten enthalten die Farbwerte im Format 1 Byte, die den Versatz in der Tabelle von der vorherigen Farbe angeben, dann 3 Byte für die Farbe selbst (mit zwei Hexadezimalziffern pro Byte). (Ein 0-Byte für den Versatz bedeutet, dass es tatsächlich der nächste Wert + 255 ist, da nicht jeder Versatz in ein Byte passt.)
Der Code analysiert die Daten, um die Tabelle mit der Farb-RGB-Zeichenfolge zu erstellen, und wendet dann die Hash-Funktion (in Perl übersetzt) auf die Eingabe an, um die passende Ausgabe aus der Tabelle auszuwählen.
Verwendungszweck:
Bearbeiten: Verringert die Größe durch Gzippen der Datendatei
quelle
EXCEL, 18 (+ 18269)
Um nur eine Grundlinie festzulegen, zeige ich die einfachste Excel-Lösung, die mir in den Sinn gekommen ist:
Code
Der Code in Excel ist sehr einfach:
Die Eingabe sollte zwischen den doppelten Anführungszeichen stehen.
Daten
Die Daten sollten in einer CSV-Datei gespeichert werden und ungefähr so aussehen:
Wenn ich auf die CSV klicke, wird automatisch Excel geöffnet, und die Daten werden in die Spalten A und B gestellt. Möglicherweise benötigen Sie ein anderes Trennzeichen.
quelle
Ruby,
5.37988 + 9 + 5.220 = 5.317 Bytes+9 Bytes für
-rdigest
Flag.... sowie ein 5.220-Byte-Wörterbuch als Binärdaten, die aus STDIN (oder dem Dateinamenargument) gelesen wurden. Sie finden das Wörterbuch im Format xxd im folgenden Ausschnitt. Das Programm verwendet einen Farbnamen als Argument, sodass Sie ihn folgendermaßen aufrufen:
Wenn jemand eine kürzere Methode zum Lesen einer Datei und zum Verwenden eines Farbnamens als Argument finden kann, hinterlassen Sie bitte einen Kommentar.
$*
(ARGV) und$<
(ARGF) interagieren auf seltsame und okkulte Weise, ergo$*.pop
.Wörterbuch (xxd Format)
Code-Snippet anzeigen
Erläuterung
Codierung des Wörterbuchs
Der Aufbau des Wörterbuchs ist sehr einfach. Ich nehme den hexadezimalen MD5-Hash des Farbnamens und verkette die zweite bis sechste hexadezimale Ziffer (die zufällig für jede Farbe eindeutig ist) mit dem 6-stelligen Farbcode. Ich füge diese zu einer einzelnen Zeichenfolge mit 10.439 Hexadezimalziffern zusammen. Dann konvertiere ich dies in äquivalente 5.219,5 Bytes, die rechts mit Nullen aufgefüllt sind, um gerade 5.220 Bytes zu erhalten.
Lustige Sache: Ich habe versucht, das Wörterbuch zu komprimieren und habe sogar
zopfli -i100
eine 40 Bytes größere Datei erstellt . Nur zum Spaß habe ich die Entropie des binären Wörterbuchs berechnet und siergb.txt
beträgt 99,8% (gegenüber beispielsweise 61,2%). Nicht schlecht!Hier ist der Code, der das Wörterbuch generiert:
Das Wörterbuch entschlüsseln und durchsuchen
Dies ist das genaue Gegenteil von dem oben Gesagten. Zuerst konvertiere ich die Binärdaten in ihre 10.439-stellige hexadezimale Darstellung. Dann nehme ich die Eingabezeichenfolge (Farbname), erhalte die zweite bis sechste Hexadezimalziffer des MD5-Hashs und benutze einen regulären Ausdruck, um diese Ziffern in der 10.439-stelligen Hexadezimalzeichenfolge bei einem durch 11 teilbaren Index zu finden und die folgenden 6 Ziffern zurückzugeben , das sind die entsprechenden Farbcodes. Zum Beispiel für den Hash
b9ca5
( „wolkige blue“), wird der folgende reguläre Ausdruck konstruiert:/^.{11}*b9ca5\K.{6}/
. Der\K
Operator verwirft die Übereinstimmung bis zu diesem Punkt, sodass nur die letzten sechs Zeichen zurückgegeben werden.quelle
pink/purple
ist#a6814c
, aber die richtige Antwort ist#ef1de7
.Perl, 7.375 Bytes
Speichert leicht komprimierte Daten (
grey
->E
usw.) als komprimierte Binärdaten, erweitert sie zu einem Hash und gibt den passenden Schlüssel zurück, nachdem Leerzeichen in der Eingabe durch ersetzt wurden_
. Ich finde es nicht so toll und bin mir sicher, dass andere intelligentere Methoden zum Komprimieren der Daten haben werden. Vielleicht spiele ich später damit.Hier steht ein reversibler Hexdump zur Verfügung, der mit diesem Skript erzeugt wurde .
Verwendungszweck
quelle
Ruby,
1213112030 +-p
= 12033 BytesDie Byteanzahl wird nach dem Ersetzen
<compressed text>
durch die Rohdaten in http://pastebin.com/xQM6EF9Q angegeben . (Stellen Sie sicher, dass Sie die Rohdaten aufgrund der Registerkarten in der Datei erhalten)Ich könnte den Text wirklich weiter verkleinern, aber ich bin jetzt seit ein paar Stunden dabei und muss schlafen.
Die Eingabe ist eine von STDIN eingespeiste Zeile ohne nachfolgende neue Zeile. Das Hinzufügen einer nachfolgenden Newline erfordert +3 Bytes, indem
($_+?\t)
auf geändert wird(chomp+?\t)
.quelle
BASH + bzip2,
805868096797 BytesDie ursprüngliche Liste wurde nach dem Komprimieren in einer Datei gespeichert, nicht sicher, ob dies zulässig ist.
Rufen Sie an mit:
quelle
dusty teal
fehl. Lies alle Argumente mit$*
oder so.bzgrep ..... c
stattdessen verwendenPython, 9360 Zeichen
Verwendet keine Komprimierungsbibliothek. Ich werde es für eine Weile als Rätsel belassen, wie es funktioniert, und dann einen Link zur Technik veröffentlichen. Natürlich könnte es durch Speichern der Daten in einem Binärformat kürzer gemacht werden, aber das ist eine Übung für ein anderes Mal.
Erläuterung:
Verwendet eine Anpassung des Codes von http://stevehanov.ca/blog/index.php?id=119 , um eine minimale perfekte Hash-Suche von Farbnamen zu Farbcodes zu generieren.
quelle
Python 3, 4927
182 Code + 4745 Datendatei
Theorie der Arbeitsweise:
md5((67*s).encode('ascii')).digest()[5:7]
ist ein perfekter Hash von den Farbnamen bis zu einem 2-Byte-Wert. Die Binärdatei ist einfach eine Liste von 5-Byte-Blöcken - 2-Byte-Hash und 3-Byte-Farbe. Der Code hasht den eingegebenen Farbnamen und durchsucht die Daten, um eine Übereinstimmung zu finden.Der Code zum Generieren der Binärdatei:
Hier ist der Code, mit dem ich einen perfekten Hash gefunden habe. Nichts Besonderes, nur drei verschachtelte Schleifen: Anzahl der Wiederholungen des Namens (z. B. 'blau', 'blau-blau', ...); die verfügbaren Hash-Algorithmen; und die Offsets in den Hashes. Es werden Kombinationen ausgedruckt, für die keine Kollisionen vorliegen.
quelle
Python 3, 296 + 3960 = 4256 Bytes
Ich habe es nicht benutzt
gperf
, weil es zu langweilig wäre, diesen Trick einfach zu wiederholen. Stattdessen habe ich eine Brute-Force-Lösung von Grund auf neu erstellt und daher ist die Größe nicht optimal (aber auch nicht schlecht).Ich habe jedoch herausgefunden, wie man Farben effizienter komprimiert - sie werden sortiert und auf 4 Bytes ausgerichtet, was LZMA zufällig ausnutzt. (die Farben werden auf 2180 Bytes komprimiert)
Um die Farbe nach Namen zu finden, wird eine 15-Bit-Hash-Funktion verwendet. Theoretisch könnte es mit weniger Bits gefunden werden (Nummern 0..949 können mit 10 Bits codiert werden), aber mein Computer könnte nichts besseres finden, es ist zu viel Arbeit.
Der Code nimmt Eingaben von stdin entgegen und gibt die Antwort aus.
Der Code:
Datendatei (binär, sollte benannt
a
und im selben Ordner abgelegt werden):Wie läuft man:
quelle
C 19.566 Bytes
Eine miserable 19.566 Bytes.
Bog-Standard C. Die Datei rgb.txt wird über stdin weitergeleitet. Die zu findende Farbe wird als erstes Argument angegeben.
Damit:
./xkcd "bright sea green" < colors.txt
Gibt:
bright sea green -> #05ffa6
quelle
Java,
79787435 BytesDer Code ist 293 Bytes, die Daten sind 7.142 Bytes
Golf gespielt:
Ungolfed:
Die Datei mit dem Namen "c" im Programm ist das Ergebnis der umgekehrten Operation dieses Programms: Nehmen Sie den Hash-Code jedes Schlüssels in der Eingabedatei und speichern Sie ihn mit der ganzzahligen Darstellung des Farbwerts. Das geht in einen Objektausgabestream, einen GZip-Ausgabestream, dann einen Dateiausgabestream. Dieses Programm liest es durch die inversen Eingabeströme.
Die standardmäßigen Java-Hash-Codes aller Farben sind in diesem Datensatz eindeutig, sodass ein guter 32-Bit-Schlüssel in der Hash-Map erstellt wird. Der Wert ist bereits eine Ganzzahl. Sie müssen ihn also nur als Hex-Zeichenfolge formatieren, die bei Bedarf mit sechs Ziffern aufgefüllt und mit einem Rautezeichen versehen ist.
quelle
Java, 4649 Bytes
Java-Code: 497 Byte, Datendatei: 4152 Byte
Die Datei finden Sie hier
ungolfed:
Das Programm verwendet eine verbesserte Version von Java-Hashcode, die nur 17 Bit verwendet:
Die Farben werden nach zunehmenden Blauanteilen sortiert. Sie sind in 18 Bits gespeichert: 8 für Rot, 8 für Grün und 2 für Delta-Blau.
Gesamtdateigröße: 949 Farben * (18 + 17) = 33.215 = 4152 Byte
quelle
JavaScript (Node.js), 10785 Byte
Verwendungszweck:
Codierte Daten .
quelle
MATLAB, 94 + 7,243 = 7,337 Bytes
Generieren Sie die MAT-Datei "h.mat" mit der Variablen "c", die eine sortierte Liste der CRC32-Prüfsummen der Namen enthält (c = java.util.zip.CRC32; c.update (uint8 (x)); c.getValue ();) und dieselbe sortierte Liste der konvertierten Hex-Codes der Farben (sscanf (x (:, end), '% x')) wie "e". Dies sollte das Dateiformat (R2013b, v7) mit einer Größe von 7,243 Byte haben.
Die Funktion ist wie folgt
Es nutzt die eingebaute Komprimierung der MAT-Dateien und die Unterstützung von Java für die CRC32-Funktion.
quelle
Los, 6709 Bytes
Der Code ist 404 Bytes, die Daten sind 6305 Bytes
Die Daten sind mit verschlüsselt
xxd -p
. Extrahieren Sie in eine Datei einfach Namenf
mitxxd -r paste f
. Der Code kann als ausgeführt werdengo run file.go "tree green"
quelle
C #, 6422 Bytes
Code ist 575 Bytes, Daten sind 5847 Bytes
Die Daten befinden sich in einer benachbarten GZipped-Datei, die eine transformierte Darstellung der Originaldaten enthält. Farbwörter, die mehr als einmal vorkommen, werden extrahiert und in einer Kopfzeilentabelle am Anfang der Datei abgelegt, der eine Länge von einem Byte vorangestellt wird.
Dateneinträge (nach dem Header) bestehen aus einer Reihe von:
Jeder Eintrag wird entweder mit 0xFF, 0xFE, 0xFD abgeschlossen, was anzeigt, dass das nächste, zwei oder drei folgende Byte den Farbwertoffset darstellt.
Die Tabelle wird in der angegebenen Reihenfolge analysiert und der Farbwert wird akkumuliert, bis eine mit der Eingabe übereinstimmende Zeichenfolge gefunden wird.
Reduzierter Dekomprimierungs- / Lookup-Code:
Datenkomprimierungscode
quelle
C # 7.209 Bytes: 6.643 Bytes Daten + 566 Bytes Code (878 Bytes nicht minimiert)
Github Repo ist hier: https://github.com/nbcarey/color-map
Farbnamen werden in der Datendatei mit dem FNV-32-1a-Hash komprimiert, da dieser Hash-Algorithmus für diesen Satz von Farbnamen günstigerweise kollisionsfrei ist. So wird jeder Farbname als 4 Bytes gespeichert.
Jede Farbe wird als 3 Bytes gespeichert (je 1 für Rot, Grün und Blau). Keine Magie da.
Folglich belegt jede Zuordnung des Farbnamens zum RGV-Wert 7 Byte in der komprimierten Datei.
Dies ist eine einzeilige Version des FNV-32-1a-Hashes (unter der Annahme, dass die Zeichenfolge nur einfache ASCII-Zeichen enthält):
Diese komprimierte Datendatei befindet sich im Github-Repository unter https://github.com/nbcarey/color-map/blob/master/color-map/hashed-color-map.dat
Hier ist der minimierte Code:
Und hier ist von Menschen lesbarer Code:
quelle
PHP, 5014 Bytes
Es ist nicht das Beste, aber es ist spät und ich muss etwas schlafen. :-)
Das Schöne an PHP ist, dass Sie Nutzdaten in Ihr Skript einbinden und die Datei selbst lesen können, sodass das Skript autark ist. Laden Sie es einfach herunter , führen Sie es aus und Sie werden zur Eingabe des Farbnamens aufgefordert.
Der grundlegende Trick besteht darin, die Farbnamen zu hashen und minimal identifizierende Teilzeichenfolgen für diesen Hash zu generieren. Ich fand, dass 4 Zeichen eines SHA1-Hashes ausreichen, die ersten 3 und die 17., um alle diese Farben eindeutig zu identifizieren. Der Schlüssel ist sowohl binär als auch der Farbcode, der günstigerweise ein Byte pro Farbkanal beträgt. Jeder Eintrag belegt also 5 Bytes, was einer Nutzlast von 5 x 949 = 4745 Bytes entspricht (die magische Zahl, die Sie im Code sehen).
Komprimierung hat nicht viel geholfen, bzip2, LZMA hat alle größere Dateien erstellt, also ohne weitere Tricks, dies ist so komprimiert, wie es für diesen Ansatz gilt.
quelle
Bash + (coreutils, gzip, xxd, openssl, sed, grep), 4946 Bytes
Daten: 4482 Bytes, Code: 464 Bytes
Die Daten können in base64 finden hier . Ich weiß, dass Code mehr Golf spielen kann. Jetzt zu müde: / Anregungen sind willkommen :-)
Erläuterung
Hier sind die Aktionen, die ich nach dem Entfernen des Lizenzkommentars an der Originaldatei durchgeführt habe.
openssl dgst -md5 -binary|base64
base64
Verwendet einen Satz von 64 Zeichen, um die Daten darzustellenA-Za-z0-9+/
. Ich hatte also gehofft, 2 Bytes zu finden, da alle Einträge 494 und 64 * 64 = 4096 waren, aber ich konnte keine finden. Ich habe auch versucht, eindeutige 2-Zeichen-Einträge zu finden, indem ichsha512
in Schritt eins verwendet habe, aber ohne Glück. Also blieb ich bei diesen 3 Bytes für die Farbnamen.(echo '0:';echo -n "$line"|cut -d '#' -f 2)|xxd -rp -l 16|base64
zopfli -i1000
die Datei komprimiert.Die Ergebnisdatei vor der Komprimierung würde also so aussehen:
Ich habe auch andere Komprimierungsprogramme ausprobiert, aber mit den schlechtesten Ergebnissen, außer
zopfli -i0000 --zlib
mit 4470 Bytes undzopfli -i10000 --defalte
mit 4464, aber ich war nicht sicher, wie ich dort Formate dekomprimieren sollte.Um den Farbcode zu finden, mache ich die umgekehrten Aktionen. Ich erstelle den dreistelligen Code aus dem angegebenen Namen und rekonstruiere teilweise die ursprünglichen Farbcodes. Zum Beispiel
adobe
erstelle ich alles, was anfängt mitX
:Dann greife ich nach der
Xqy
Linie und gebe den zweiten Teil zurück, der die Farbe hex hat.Ich habe dieses Rätsel wirklich genossen und es gibt hier viele gute Antworten. Vielen Dank und gute Arbeit an alle!
quelle
Bash + Coreutils / xxd, 4064 Bytes
Daten 3796 Bytes ( hexadezimaler Speicherauszug der Datendatei )
Bash 268 Bytes
Ungolfed
Die allgemeine Idee besteht darin, 32-Bit-Felder zu durchsuchen, den passenden eindeutigen 14-Bit-Hash zu finden und den Farbcode an dieser Stelle auszudrucken. Die 18-Bit-Farbkodierung nutzt den Ansatz von Super Chafouin.
Der eindeutige 14-Bit-Hash beginnt mit einer Teilmenge von 14 der Bits aus der 128-Bit-MD5-Summe. Um diese Bits zu finden, habe ich hier einen genetischen Algorithmus verwendet, der in C ++ codiert ist . Der Code lädt eine feste Datei mit dem Namen "data" vor, bei der es sich nur um die md5sum handelt, eine pro Zeile in binärer Form. Wenn Sie das in Rezeptform benötigen, erstellt dies die Datendatei:
Ich finde die besten 14-Bit-Kandidaten (die ich bisher gesehen habe) aus diesem Code in Generation 2, aber dieser Satz weist zwei Kollisionen auf. Insbesondere: "Schlamm" und "blassviolett" werden auf denselben Wert abgebildet, und "aquablau" und "hellgrün" werden auf denselben Wert abgebildet. Da es nur zwei Kollisionen gibt und ich nichts Besseres gefunden habe, disambiguiere ich sie einfach. Es stellt sich heraus, dass die Hälfte dieser Bucket-Werte nicht verwendet wird.
Ich habe bereits versucht, Komprimierung auf d; Aber weder bzip2, noch gzip, noch xz scheinen die Größe von d zu verringern.
quelle
Groovy,
153 + 10.697 = 10.850,253 + 9870 = 10.123 BytesIch entschied mich für eine Lösung, die nur eine Datei umfasste, und verschlüsselte daher (aus Platzgründen) eine GZIPped-CSV-Version der Daten in Unicode-Zeichen 0x0020-0x007E (was würde ich für eine Base-95-Codierung halten?). Der Code ist 253 Zeichen, der Inhalt des Strings ist 10123 Zeichen.
Aus Gründen der Lesbarkeit gilt das Gleiche mit Ausnahme des codierten Texts:
Meine ursprüngliche Lösung war eine einfachere Base 64-Codierung mit dem eingebauten Encoder
Aus Gründen der Lesbarkeit gilt Folgendes mit Ausnahme des Texts:
quelle