Das PBM-Format (Portable BitMap) ist ein sehr einfaches ASCII-Schwarzweiß-Bitmap-Format.
Hier ist ein Beispiel für den Buchstaben 'J' (vom Wikipedia-Link kopiert und eingefügt):
P1 # Dies ist eine Beispiel-Bitmap des Buchstabens "J" 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Es ist Zeit, ein kleines Tool zu erstellen, um Dateien in diesem kleinen Format zu generieren!
Ihr Ziel ist es, das kürzeste Programm (in jeder Sprache) zu schreiben, das den folgenden Regeln entspricht:
- Ihr Programm nimmt einen String von stdin (zum Beispiel
CODEGOLF.STACKEXCHANGE.COM!
) - Es wird eine PBM-Datei mit einer Bitmap-Darstellung (lesbar) der Zeichenfolge generiert.
- Jedes Zeichen ist als 8x8-Gitter aufgebaut.
- Sie müssen die Zeichen [AZ] (Großbuchstaben), ein Leerzeichen, einen Punkt ('.') Und ein Ausrufezeichen ('!') Unterstützen.
- Keine externen Bibliotheken erlaubt (sicherlich keine PBM-bezogenen)!
- Der verwendete Zeichensatz darf nicht einfach außerhalb Ihres Programms liegen. Ein Teil der Herausforderung besteht darin, die Charaktere effizient zu speichern ...
Das Testen der Gültigkeit des PBM-Formats kann mit dem GIMP (oder anderen) durchgeführt werden. Führen Sie die Ein- und Ausgabe der Samples vor!
Die kürzeste Lösung erhält am 31.01.2012 die Antwortpunkte.
Viel Spaß beim Golfen!
PS: Ich habe ein Kopfgeld (prozentual gesehen einen großen Teil meines Codegolf-Rufs) hinzugefügt, um (hoffentlich) mehr Konkurrenten anzuziehen.
code-golf
string
graphical-output
ChristopheD
quelle
quelle
letters
anderen Worten) enthält. Nicht anders als das Beispiel, das mit verknüpft ist.Antworten:
GolfScript, 133 Bytes
Dies basiert auf meiner 164-Byte-Perl-Lösung und verwendet dieselbe 4 x 5-Pixel-Nibble-gepackte Schriftart. Nochmals, ich gebe zuerst die lesbare Version:
Hier
FONT DATA HERE
stehen 71 Bytes für binär gepackte Schriftdaten. Die Codierung unterscheidet sich geringfügig von der in der Perl-Version: Anstatt die gepackte Zeichenfolge in Leerzeichen zu teilen, erweitere ich sie zuerst und teile sie dann im Nibble auf3
(ausgewählt, weil sie zufällig nirgendwo in der Schriftart vorkommt).Da die Schriftdaten im eigentlichen Skript nicht druckbare Zeichen enthalten, gebe ich sie unten als Hex-Dump aus. Verwenden Sie
xxd -r
das Hex - Dump zurück in ausführbaren GolfScript Code zu aktivieren:Im Gegensatz zu dem Perl - Script, druckt dieser Code alle Zeichen außerhalb der eingestellten
A
-Z
,!
,.
,space
wie lustig aussehenden kleine Kringel. Das Ersetzen der Schnörkel durch Leerzeichen würde 2 zusätzliche Zeichen kosten; Eine vollständige Entfernung würde 4 kosten.Dies ist mein erstes GolfScript-Programm überhaupt, daher würde ich mich nicht wundern, wenn noch Optimierungsbedarf besteht. So funktioniert das:
{91,65>"!. "+?}%:s
ordnet die gültigen Eingabezeichen (A
-Z
,!
,.
,space
) auf die Zahlen 0-28 und weist das Ergebniss
. Alle Zeichen außerhalb des gültigen Satzes werden mit -1 verknüpft, was beim Drucken zu Kringeln führt."P4"\,8*8
schiebt die Werte "P4", 8 mal die Länge der Eingabe und 8 auf den Stapel. Wenn diese am Ende gedruckt werden, bilden sie den PBM-Header.{16base}%[3]/
Nimmt die vorhergehende Zeichenfolge von Schriftartdaten, teilt jedes Byte in zwei Halbbytes auf und teilt das Ergebnis in durch den Wert begrenzte Blöcke auf3
. Durchlaufen Sie{:p;{[p=0]0=}s%}%
dann diese Blöcke, indem Sie zuerst jeden Block der Variablenp
zuweisen und dann die neu zugeordnete Eingabezeichenfolge durchlaufens
und jedes Zeichen durch den Wert am entsprechenden Offset in ersetzenp
. Das witzig aussehende Konstrukt[p=0]0=
macht dasselbe wiep=
, außer dass es für alle Offsets nach dem Ende von 0 zurückgibtp
; Ich mag es nicht wirklich, aber ich konnte keinen kürzeren Weg finden, um damit umzugehen.Zum Schluss
]n*
nimmt man alles auf den Stapel (die drei Header-Werte und das Bilddaten-Array) und fügt sie mit Zeilenumbrüchen zum Drucken zusammen.quelle
Perl, 164 Bytes, keine zlib / gzip-Komprimierung
Nachdem ich über das Problem geschlafen hatte, fand ich eine viel kürzere Lösung als meine erste. Der Trick besteht darin, eine kleine Lücke in den Regeln auszunutzen: Die Zeichen müssen jeweils 8 x 8 Pixel groß sein, aber nichts sagt, dass sie den ganzen Raum ausfüllen müssen . Also habe ich meine eigene 4 mal 5 Pixel große Schrift gezeichnet, mit der ich zwei Zeichen in 5 Bytes packen kann.
Die Ausgabe sieht folgendermaßen aus:
(skaliert x 4)
(Originalgröße)
Lassen Sie mich vor der Eingabe des eigentlichen Codes mit den eingebetteten Schriftartdaten eine de-golfed-Version anzeigen:
Im eigentlichen Code wird das
PACKED FONT DATA
durch eine Binärzeichenfolge ersetzt, die aus acht Zeilen mit Leerzeichen (vier Zeilen mit 14 Byte und eine Zeile mit 13 Byte sowie drei einzelnen Nullbytes für die leeren Zeilen) besteht. Ich habe meine Schriftart bewusst so gestaltet, dass die gepackten Daten keine Leerzeichen, einfachen Anführungszeichen oder Backslashes enthalten, sodass sie in codiert werden könnenqw'...'
.Da die gepackte Schriftzeichenfolge nicht druckbare Zeichen enthält, habe ich das eigentliche Skript als Hex-Dump bereitgestellt. Verwandle
xxd -r
es wieder in ausführbaren Perl-Code:So funktioniert das:
Die erste Zeile (in der de-golfed Version) liest eine einzige Zeile eingegeben wird , teilt sie in einer Reihe von Zeichen (bequem alle nachgestellten newlines Weglassen) und ordnet die Buchstaben
A
anZ
und die Zeichen!
und.
den Zeichencodes 0-28, die Normalerweise entsprechen nicht druckbare Steuerzeichen in ASCII / Unicode. (Ein geringfügiger Nebeneffekt davon ist, dass alle Tabulatoren in der Eingabe alsJ
s gedruckt werden .) Das Leerzeichen wird nicht zugeordnet, da die Ausgabeschleife ohnehin alle Codes über 28 in Leerzeichen verwandelt.In der zweiten Zeile wird nur der PBM-Header gedruckt. Es verwendet die Perl 5.10-
say
Funktion, sodass Sie dieses Skript ausführen müssen, damitperl -M5.010
es funktioniert.Die Ausgabeschleife erstellt eine durch Leerzeichen getrennte Liste gepackter Bildzeilen und ordnet diese der
$p
Reihe nach zu. (Ich habe die Schriftart so entworfen, dass die gepackten Daten keine Leerzeichen oder'
Zeichen enthalten.) Anschließend werden die eingegebenen Zeichen in einer Schleife@a
mit dem Perl-vec
Befehl überflogen, um das 4-Bit-Halbbyte zu extrahieren, das dem zugeordneten Zeichencode aus der Bildzeile entspricht. Füllt es mit einem 8-Bit-Byte auf und druckt es aus.Alte Antwort, 268 Bytes:
Dies ist ein schneller und schmutziger erster Versuch. Ich habe PleaseStands Schriftart gestohlen und zusammen mit meinem Quellcode komprimiert. Da das resultierende Skript größtenteils nicht druckbar ist, ist hier ein Hexdump. verwendet
xxd -r
es in ausführbaren Perl - Code zu aktivieren:Der dekomprimierte Perl-Code besteht aus der folgenden Präambel:
gefolgt von acht Wiederholungen des folgenden Codes:
wird
BITMAP DATA HERE
durch 29 Bytes ersetzt, die eine Zeile der Schriftart codieren.quelle
8086 Maschinencode
190 Bytes (122 Bytes im BIOS)
Hier ist die Base64-codierte WinXP / MSDos .COM-Datei:
(Verwenden Sie etwas wie diese ) , um den Text zu entschlüsseln und speichern als „pbm.com“. Geben Sie dann an der Eingabeaufforderung Folgendes ein:
Ich habe dies auf meinem WinXP-Rechner sowohl mit der Standard-Eingabeaufforderung als auch mit DosBox V0.74 getestet.
AKTUALISIEREN
Diese Version ist 190 Bytes groß und verwendet Ilmari Karonens winzige Schrift (hier kein Zugang zum BIOS!): -
quelle
puts
bei Ruby um eine externe Bibliothek handelt. Ja, es werden die BIOS-Schriftarten verwendet, auf die über eine Zeiger-Dereferenzierung zugegriffen wird (es gibt keineload
Operation, um die Schriftarten in den RAM zu laden ). Vielleicht die Regeln zu weit verbiegen. Ich wäre damit durchgekommen, wenn dieseShell-Skript (Code + Daten = 295 Zeichen)
Ich hoffe, tail, gzip und dd zählen nicht als "externe Bibliotheken". Führen Sie so
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. Die Schriftart, die ich verwendete, ist Small Fonts Größe 7,5, obwohl ich den Abseiler vom Q abschneiden musste.Beispielausgabe
Code (137 Zeichen)
Komplettes Drehbuch
(
xxd -r
zum erneuten Erstellen der Originaldatei verwenden)Erläuterung
od
ist das Standard-Dienstprogramm "octal dump". Die-tu1
Option weist es an, stattdessen einen dezimalen Speicherauszug einzelner Bytes zu erstellen (eine ausreichende Umgehung für das Fehlen von asc (), ord (), .charCodeAt () usw. durch Bash).P4
ist die magische Zahl für eine PBM-Datei im Binärformat, die acht Pixel in jedes Byte packt (im GegensatzP1
zur PBM-Datei im ASCII-Format). Sie werden sehen, wie nützlich dies ist.dd
. (tail -2 $0
Extrahiert die letzten beiden Zeilen des Skripts. Die komprimierten Daten enthalten ein 0x0a-Zeilenvorschubbyte.) Es kommt vor, dass acht Pixel die Breite eines einzelnen Zeichens sind. Die Null-Bytes, die die Lücken zwischen den unterstützten Zeichen füllen, können leicht komprimiert werden, da sie alle gleich sind.wc -c
der eingegebene Dateiname "8" nach der Anzahl der Bytes ausgegeben wird .quelle
Python 2,
248247 BytesVerwendet eine 3x5-Schriftart, die in eine druckbare Zeichenfolge mit 3 Bytes pro Zeichen gepackt ist. Die Schriftart ist gut lesbar, obwohl das n in Kleinbuchstaben geschrieben ist und das v möglicherweise mit au verwechselt wird, wenn es nicht im Kontext gesehen wird.
Tatsächliche Größe:
X3 gezoomt:
Der Ausgang ist ein PBM vom Typ P1, wie im Beispiel in der Challenge gezeigt. Es war eine lustige Herausforderung.
quelle
Ruby 1.9, 346 Bytes (122 Code + 224 Bytes Daten)
Hier ist das Ergebnis:
(Es ist schön, nicht wahr?)
Die Schriftart wurde von
figlet -f banner -w 1000 $LETTERS
und dieses Skript generiert .Laufen Sie mit
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.Das Skript generiert alle Zeilen und druckt sie einfach aus.
Hier ist ein Hexdump (Verwendung
xxd -r
):Bei Verwendung von goruby werden 93 Byte Code benötigt:
Wenn Sie ZLib verwenden, reduzieren Sie die Datengröße auf 142 Bytes anstatt auf 224, aber fügen Sie dem Code 43 Bytes hinzu, also 307 Bytes:
Das ergibt insgesamt 268 bei Verwendung von goruby:
quelle
Java
862826:Hier ist ein anderer Ansatz. Ich denke 'awt' zählt nicht als externe lib.
Und ungolfed:
Robot ist die irgendwie merkwürdige Art von Java, getPixel aufzurufen. Ich erstelle eine Beschriftung mit dem Alphabet und messe, wo sich für jeden Buchstaben ein Pixel befindet.
Bei der Malmethode
int py = (y < 3) ? y : y +1;
und(8*a+x+17+x/4, py+81)
ist es die komplizierte Art, die Position in der Schrift anzupassen. Huuuh! Andernfalls werden 9 Zeilen benötigt, und bei jedem vierten Buchstaben wird ein zusätzliches Pixel horizontal eingefügt. Versuch und Irrtum brachten mich zu dieser Lösung.Dann wird der Header der PBM und jede Zeile der Nachricht geschrieben. Die Nachricht wird als Titel des Frames übergeben.
Das ist es. Nicht der kürzeste Code, aber kein manuelles Zeichnen der Schrift war erforderlich.
Vielleicht könnte es in BeanShell oder Scala kürzer sein.
Und jetzt - wie sieht es aus?
Mehrere Zooms angewendet:
Unzoomed:
Nicht, dass die Anzahl der Zeichen der Anzahl der Zeichen entspricht, die von der Perl-Lösung gemischt wurden.
(Ein bisschen mehr Golf gespielt. Robot statisch gemacht, wodurch eine Ausnahmeerklärung vermieden wird.)
quelle
eog
(Eye of Gnome) und einen Screenshot verwendet. Ich werde eine unskaliertejpg
-Version hochladen ; Möglicherweise verwendet Ihr Browser eine Interpolation nach dem nächsten Nachbarn :).C ++ ZU GROSS, UM ZU GEWINNEN
Ich habe ein voll ausgestattetes PPM-Zeichenprogramm in C ++ geschrieben, mit meiner eigenen Bitmap-Schriftart. Selbst wenn alle nicht benötigten Funktionen wegfallen, ist es im Vergleich zu den Antworten hier aufgrund der Definition für die Schriftart immer noch riesig.
Wie auch immer, hier ist die Ausgabe für HELLO WORLD:
Und der Code:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Wenn Sie interessiert sind, dann ist die volle PPMDraw Bibliothek hier :
quelle
SmileBASIC, 231 Bytes
Jedes Zeichen enthält nur 2 verschiedene Zeilenmuster, ausgewählt aus einer "Palette" von 8 Kombinationen. Die Daten für jedes Symbol werden in 1 Byte gespeichert, wobei die Palette separat gespeichert wird.
quelle