Die Golf-Herausforderung besteht darin, das folgende Bild in einer Quelldatei zu codieren und zu komprimieren.
Um dies zu tun Sie müssen 3 Funktionen schreiben: red
, green
und blue
die akzeptieren x / y - Koordinaten des Bildes und gibt die entsprechenden R / G / B - Pixel - Wert zwischen 0-255.
Hier ist der C / C ++ - Testcode:
#include <stdio.h>
#include "your_file"
int main() {
int x, y;
for(y = 0; y < 32; ++y)
for(x = 0; x < 32; ++x)
printf("%i %i %i\n", red(x, y), blue(x, y), green(x, y));
}
Und die Ausgabe: http://pastebin.com/A770ckxL (Sie können dies verwenden, um Ihre Bilddaten zu generieren)
Regeln & Details:
- Dies ist ein Golf
- Nur Ihr Code / Ihre Datei wird mit Golf gespielt - der Testcode ist separat
- Der verwendete Zeichensatz ist ASCII. Steuerzeichen in Zeichenfolgen dürfen jedoch nur verwendet werden, wenn sie maskiert sind (wie '\ n' und '\ r' usw.).
- Alles muss in der Quelle enthalten sein - kein Laden von Dateien
- Ihre Ausgabe muss mit der Beispielausgabe übereinstimmen. Dies bedeutet verlustfreie Komprimierung.
Sprachen:
Das Problem wurde mit Blick auf C / C ++ geschrieben, aber ich entferne diese Einschränkungen. Trotzdem werde ich immer noch empfehlen, sie zu verwenden.
Antworten:
C,
796 754 712 703 692 685 682 670 666 662 656648 ZeichenÄnderungsprotokoll:
return
um das#define
, ersetztif
mit?
Anweisungen (dank @FUZxxl), das Entfernenint
von den Funktionen Parameterliste.#define
p[]
undh[]
einige weitere?:
Verbesserungenb
soi
wird nicht mehr benötigt.m=b
stattm=11
undn<2e3
statti<356
- diese sind nahe an undefiniertem Verhalten / Speicherbeschädigung, aber es scheint, ich habe Glück :)k
ist jetzt (32,16,8,4,2,1,0) anstelle von (5,4,3,2,1,0). Gotcha, DC;)p[]
undh[]
, umgewandelth[]
in achar*
- awwww, ist ein schläfriges Kätzchen drin^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, sodass wir 64-127 anstelle von 0-63 zuordnen können und keinen Bitindex mehr benötigenk
. Danke @Piotr Tarsa . Ersetzt?:
(GCC-Erweiterung) durch||
. Danke @JamesBp[]
)Das Bild wird in eine Base64-ähnliche Zeichenfolge (ASCII 37-100) konvertiert, wobei die Huffman-Codierung verwendet wird, um die Farben 0-9 mit 3-6 Bit und eine Sonderfarbe 10 (Pixel ist dieselbe wie die vorherige) mit nur 1 Bit zu codieren.
Kopierte zwei Dinge aus Bunnits Antwort, wobei das
#define
und das gesamte Bild jedes Mal vollständig dekodiert werden, wennred
/green
/blue
aufgerufen wird. Es gibt Raum für zusätzliche Verbesserungen, also erwarten Sie einige Updates :) Ich bin mir nicht sicher, ob der Code eingehalten wird. GCC 4.6.1 wurde zum Kompilieren und Testen verwendet.In Bezug auf die Komprimierung denke ich, dass arithmetische Codierung hilfreich wäre, da die Verteilung ziemlich verzerrt ist, aber möglicherweise wäre der Code-Overhead in diesem Fall zu hoch. Das LZW sollte auch sehr gute Arbeit leisten. Die Farben sind ziemlich lokal, daher könnte eine adaptive Codierung eine Idee sein.
Mehr lesbare 754-Zeichen-Version mit einigen Kommentaren:
quelle
int
aus den Parameterlisten entfernen, um weitere Bytes zu entfernen.m=m>9?c[n-1]:m;
fürif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
warum nichtk>=0?:(j=b[i++]-37,k=5);
? (Dieser Code verwendet eine C-Erweiterung von gcc,x=a?:b
ist der gleiche wiex=a?a:b
, mit dem Unterschied, dass a nur einmal ausgewertet wird.red(x,y){while(i<356){--k>=0?:(j=b[i++]-37,k=5);l*=2;if(j&(1<<k))l++;for(m=0;m<11;m++)l!=h[m]?:(m=m<=9?:c[n-1],c[n++]=m,l=0,m=12);}return P;}
Python (
684592 Zeichen)Da diese Herausforderung nun für alle offen ist, warum nicht! Es ist die bekannte zlib -> base64-Codierungsroute, also entschuldige ich mich dafür. Hoffentlich wird ein Eintrag mit etwas Einfallsreichtum kürzer!
Hier ist ein Testausschnitt analog zum Original:
quelle
C ++, 631 Zeichen; C - 613
Ein unärer MTF-Codierer der Basis 92, C ++, 631 Zeichen:
Und die C-Version von oben (613 Zeichen):
Nur um einen Eintrag mit Basis-95-Daten und arithmetischer Codierung + adaptivem statistischen Modell aufzunehmen.
Der Code von Schnaader verwendet ~ 438 Zeichen für Daten und nur 318 (311 ohne Maskierung).
Aber wie erwartet ist die arithmetische Codierung für eine kleine Stichprobe wie diese zu kompliziert.
(Dies sind 844 Zeichen)
Tests (von früherer Base-96-Version):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
Irgendwie isst SO 7F-Codes, also musste ich es auf base = 95 aktualisieren
quelle
C ++ -
15251004964 ZeichenErstellt ein Array z, in dem alle möglichen Farben als einzelne Ganzzahl gespeichert sind (r << 16 | g << 8 | b). Erstellt ein Array d, das {Betrag, Wert} speichert, der Wert ist die Position im Array z, der Betrag ist die Anzahl aufeinanderfolgender Pixel mit diesem Wert (dh 3,0 bedeutet, dass die Farbe t [0] in den nächsten 3 erscheint Pixel. Das tatsächliche Array von Pixeln (c) wird dann jedes Mal berechnet, wenn Rot aufgerufen wird. Der Wert im Array wird dann nach rechts verschoben und nach Bedarf UND-verknüpft, um die richtige Komponente zu erhalten.
Ich könnte wahrscheinlich ein paar weitere Zeichen (~ 50) speichern, indem ich mehr Muster aus dem Array herausnehme, wie definiert.Bearbeiten 1 - hat das d-Array für ein char-Array geändert, wobei jeder Wert um 48 versetzt ist. Dies bedeutet, dass ich es als Zeichenfolge darstellen kann, die eine Menge Kommas spart.
Bearbeiten 2 - Hat einen größeren Teil der Funktionen in der define-Anweisung entfernt.
quelle
int
int f(int x,int y)
f(x,y)
Javascript,
696694 ZeichenDanke an Schnaader für 696 -> 694.
Ich habe mir ein anderes Codierungsformat vorgestellt, nämlich die Lauflängencodierung mit einer Farbnachschlagetabelle. Es funktioniert ganz gut, weil es weniger als 16 Farben gibt und sie weniger als 16 Mal hintereinander erscheinen. Daher passt jede Pixeldefinition einschließlich der Länge in ein Byte. Ich setze die Farbe in den oberen Teil des Bytes und die Anzahl in den unteren Teil.
Am Ende stellte sich heraus, dass die base64-Zeichenfolge länger war als ich erwartet hatte (472 Zeichen), aber das Dekodierungsprogramm ist wirklich kurz.
Hinweis: Ich habe den Code aufgeteilt, um eine gute Lesbarkeit zu gewährleisten. Es muss sich in einer Zeile befinden, um ausgeführt zu werden.
Testcode:
Ich denke, das Beispielergebnis ist tatsächlich die Ausgabe von Rot, Grün, Blau (nicht Rot, Blau, Grün wie im ursprünglichen Testcode); das funktioniert bei mir sowieso so.
quelle
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
- dies spart 1 Zeichen und ist GBR-Reihenfolge anstelle von RGB.C ++, 1357 Zeichen
Ein bisschen entblößt:
C
enthält die RGB-Werte für die zehn verschiedenen Farben des Bildes.E
enthält die Daten für das Bild, wobei jedes ElementE[i]
sowohl eine WiederholungszahlE[i]/10
als auch einen Farbindex codiertE[i]%10
.quelle
int red(x,y){R Q(x+32*y)[0]}(only
# define` umwandelnreturn
, können Sie möglicherweise mehr Zeichen rasieren.Python 3 (589 Zeichen)
Testcode
Basierend auf der Lösung von Dillon Cower
quelle
PHP (5,4) - 822
Ich habe dies absichtlich getan , ohne eine der eingebauten Komprimierungsfunktionen zu verwenden . Diese Lösung ist noch nicht fertig. Ich bin mir nicht sicher, ob ich aufgegeben habe. Ich sehe Verbesserungsmöglichkeiten, aber ich kann im Moment nicht die Zeit / Willenskraft finden, um das Ganze umzugestalten. Deshalb poste ich, was ich habe bisher.
Zeilenumbrüche + Kommentare, die für 822 Byte entfernt werden sollen.
Teststummel:
Die Komprimierung der Bilddaten selbst ist ziemlich gut, aber die Funktionen zum Abrufen von RGB-Werten beanspruchen 1/4 des Codes.
Ich verwende einen benutzerdefinierten Codierungsmechanismus für base70 + Lauflänge.
Die codierten Bilddaten verweisen auf den Array-Index eines RLE, der wiederum das Array von Farben indiziert. Ich bin mir nicht sicher, wie viel Overhead dies durch direktes Referenzieren der Farben addiert oder subtrahiert.
Da es 10 Farben (0 bis 9) gibt, werden RLEs als gespeichert
run_length * 10 + colour_index
. Geben Sie eine Reihe von Codierungen zwischen 10 und 145 an, ohne mit Optimierungen basierend auf der Farbreihenfolge zu experimentieren. (dh ich könnte den Bereich 19 bis 140 einstellen, indem ich die Farben 0 bis 5, 5 bis 9 und 9 bis 0 verschiebe - aber dies kann andere Auswirkungen haben)Eine vorherige Antwort besagt, dass ihre codierten Daten 472 Bytes betragen. Meine codierten Bilddaten sind 352 Bytes, aber die Zwischen-RLE / Farbkarte (die nicht binär codiert ist) beträgt weitere 129 Bytes, was eine Gesamtsumme von 481 ergibt (sowie zusätzlichen Overhead für die Verbindung der beiden). Ich vermute jedoch, dass meine Methode für größere Bilder möglicherweise besser skaliert.
MACHEN:
global
ist eine Hündin, kann aber nicht auf Zeichenindizes für Konstanten zugreifen.quelle
C (gcc) , 602 Bytes
Probieren Sie es online aus!
Heruntergewirtschaftet
quelle