Le format PBM (Portable BitMap) est un format bitmap ASCII noir et blanc très simple.
Voici un exemple pour la lettre «J» (copiée-collée à partir du lien wikipedia):
P1 # Ceci est un exemple de bitmap de la lettre "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
Il est temps de construire un petit outil pour générer des fichiers dans ce petit format astucieux!
Votre objectif est d'écrire le programme le plus court (dans n'importe quelle langue) conforme aux règles suivantes:
- Votre programme prend une chaîne de stdin (par exemple
CODEGOLF.STACKEXCHANGE.COM!
) - Il génère un fichier PBM avec une représentation bitmap (lisible) de la chaîne.
- Chaque personnage est construit comme une grille 8x8.
- Vous devez prendre en charge les caractères [AZ] (tout en majuscules), l'espace, un point ('.') Et un point d'exclamation ('!').
- Aucune bibliothèque externe autorisée (certainement pas de bibliothèques liées à PBM)!
- Le jeu de caractères utilisé ne doit pas simplement être externe à votre programme. Une partie du défi consiste à stocker efficacement les personnages ...
Les tests de validité du format PBM peuvent être effectués avec GIMP (ou autres). Montrez les échantillons d'entrée et de sortie!
La solution la plus courte obtiendra les points de réponse le 31-01-2012.
Amusez-vous au golf!
PS: J'ai ajouté une prime (en pourcentage une énorme partie de ma réputation de codegolf) pour (espérons-le) attirer plus de concurrents.
code-golf
string
graphical-output
ChristopheD
la source
la source
letters
en d'autres termes). Un peu comme l'exemple lié à.Réponses:
GolfScript, 133 octets
Ceci est basé sur ma solution Perl de 164 octets et utilise la même police 4 x 5 pixels pleine de quartets. Encore une fois, je vais d'abord donner la version lisible:
Ici,
FONT DATA HERE
représente 71 octets de données de police compressées binaires. L'encodage est légèrement différent de celui de la version Perl: au lieu de diviser la chaîne compressée sur des espaces, je la développe d'abord, puis la divise sur le quartet3
(choisi car il se trouve que cela ne se produit nulle part dans la police).Étant donné que les données de police dans le script réel contiennent des caractères non imprimables, je les donne sous forme de vidage hexadécimal ci-dessous. Utilisez
xxd -r
pour transformer le vidage hexadécimal en code GolfScript exécutable:A la différence du script Perl, ce code imprime des caractères en dehors du jeu
A
-Z
,!
,.
,space
aussi peu gribouillis drôles prospectifs. Remplacer les gribouillis par des blancs coûterait 2 caractères supplémentaires; les supprimer entièrement coûterait 4.Il s'agit de mon tout premier programme GolfScript, donc je ne serais pas surpris s'il reste de la place pour l'optimisation. Voici comment ça fonctionne:
{91,65>"!. "+?}%:s
cartes les caractères d'entrée valides (A
-Z
,!
,.
,space
) aux numéros 0 - 28 et affecte le résultat às
. Tous les caractères en dehors de l'ensemble valide sont mappés à -1, ce qui produit les gribouillis lors de l'impression."P4"\,8*8
pousse les valeurs "P4", 8 fois la longueur de l'entrée et 8 sur la pile. Une fois imprimés à la fin, ceux-ci formeront l'en-tête PBM.{16base}%[3]/
prend la chaîne de données de police précédente, divise chaque octet en deux quartets et divise le résultat en blocs délimités par la valeur3
.{:p;{[p=0]0=}s%}%
boucle ensuite sur ces blocs, affectant d'abord chaque bloc à la variablep
, puis bouclant sur la chaîne d'entrée remappées
, en remplaçant chaque caractère par la valeur au décalage correspondant dansp
. La construction amusante[p=0]0=
fait la même chose quep=
, sauf qu'elle renvoie 0 pour tous les décalages après la fin dep
; Je n'aime pas vraiment ça, mais je n'ai pas été en mesure de trouver un moyen plus court de gérer cela.Enfin,
]n*
prend tout sur la pile (les trois valeurs d'en-tête et le tableau de données d'image) et les joint avec des retours à la ligne pour l'impression.la source
Perl, 164 octets, pas de compression zlib / gzip
Après avoir dormi sur le problème, j'ai réussi à trouver une solution beaucoup plus courte que la première. L'astuce consiste à profiter d'une faille mineure dans les règles: les personnages doivent tenir dans 8 x 8 pixels chacun, mais rien ne dit qu'ils doivent remplir tout cet espace. J'ai donc dessiné ma propre police de 4 x 5 pixels, ce qui m'a permis de regrouper deux caractères en 5 octets.
La sortie ressemble à ceci:
(mis à l'échelle x 4)
(format original)
Avant de donner le code réel avec les données de police intégrées, permettez-moi de montrer une version dé-golfée:
Dans le code réel, le
PACKED FONT DATA
est remplacé par une chaîne binaire composée de huit lignes délimitées par des espaces (quatre lignes de 14 octets et une de 13 octets, plus trois octets nuls simples pour les lignes vides). J'ai délibérément conçu ma police pour que les données compressées ne contiennent aucun espace, guillemets simples ou barres obliques inverses, afin qu'elles puissent être encodéesqw'...'
.Étant donné que la chaîne de police compressée contient des caractères non imprimables, j'ai fourni le script réel sous forme de vidage hexadécimal. Utilisez-le
xxd -r
pour le reconvertir en code Perl exécutable:Voici comment ça fonctionne:
La première ligne (dans la version dé-golfée) lit une seule ligne d'entrée, la divise en un tableau de caractères (en omettant commodément tous les retours à la ligne) et mappe les lettres
A
àZ
et les caractères!
et.
les codes de caractères 0 à 28, qui correspondent normalement aux caractères de contrôle non imprimables en ASCII / Unicode. (Un effet secondaire mineur de cela est que tous les onglets de l'entrée sont imprimés en tant queJ
s.) Le caractère d'espace n'est pas mappé, car la boucle de sortie transforme tous les codes supérieurs à 28 en blancs de toute façon.La deuxième ligne imprime simplement l'en-tête PBM. Il utilise la fonctionnalité Perl 5.10
say
, vous devez donc exécuter ce script avecperl -M5.010
pour qu'il fonctionne.La boucle de sortie prend une liste délimitée par des espaces des lignes d'image compressées et les affecte chacune
$p
à son tour. (J'ai conçu la police pour que les données compressées ne contiennent aucun espace ni'
caractère.) Elle passe ensuite en boucle les caractères d'entrée dans@a
, en utilisant lavec
commande de Perl pour extraire le quartet de 4 bits correspondant au code de caractère mappé de la ligne d'image, le remplit sur un octet 8 bits et l'imprime.Ancienne réponse, 268 octets:
Il s'agit d'une première tentative rapide et sale. J'ai volé la police de PleaseStand et l'ai compressée avec mon code source. Étant donné que le script résultant n'est pas imprimable, voici un hexdump; utiliser
xxd -r
pour le transformer en code Perl exécutable:Le code Perl décompressé se compose du préambule suivant:
suivi de huit répétitions du code suivant:
avec
BITMAP DATA HERE
remplacé par 29 octets codant une ligne de la police.la source
8086 Code machine
190 octets (122 octets en utilisant le BIOS)
Voici le fichier .COM WinXP / MSDos encodé en Base64:
(Utilisez quelque chose comme ça ) pour décoder le texte et l'enregistrer sous "pbm.com". Ensuite, à l'invite de commandes, tapez:
J'ai testé cela sur ma machine WinXP en utilisant à la fois l'invite de commande standard et DosBox V0.74.
MISE À JOUR
Cette version est de 190 octets et utilise la petite police d'Ilmari Karonen (pas d'accès bios ici!): -
la source
puts
Ruby est une bibliothèque externe. Oui, il utilise les polices bios, accessibles via une déréférence de pointeur (il n'y a aucuneload
opération pour obtenir les polices dans la RAM). Plier les règles trop loin peut-être. J'aurais pu m'en tirer si ça n'avait pas été pour ces gamins embêtants ;-)Script shell (code + données = 295 caractères)
J'espère que tail, gzip et dd ne comptent pas comme des "bibliothèques externes". Exécuter en tant que
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. La police que j'ai utilisée est de petite taille 7,5, même si j'ai dû couper le descendeur du Q.Exemple de sortie
Code (137 caractères)
Script complet
(utiliser
xxd -r
pour recréer le fichier d'origine)Explication
od
est le programme utilitaire standard "octal dump". L'-tu1
option lui dit de produire un vidage décimal d'octets individuels à la place (une solution de contournement suffisante pour le manque de bash de asc (), ord (), .charCodeAt (), etc.)P4
est le nombre magique pour un fichier PBM au format binaire, qui contient huit pixels dans chaque octet (par rapportP1
au fichier PBM au format ASCII). Vous verrez comment cela s'avère utile.dd
. (tail -2 $0
extrait les deux dernières lignes du script; les données compressées incluent un octet de saut de ligne 0x0a.) Il se trouve que huit pixels correspondent à la largeur d'un seul caractère. Les octets nuls qui remplissent les espaces entre les caractères pris en charge sont facilement compressibles car ils sont tous identiques.wc -c
imprime le nom de fichier d'entrée "8" après son nombre d'octets.la source
Python 2,
248247 octetsUtilise une police 3x5, regroupée dans une chaîne imprimable, 3 octets par caractère. La police est clairement lisible, bien que le n soit en minuscule et que le v puisse être confondu avec au s'il n'est pas vu dans son contexte.
Taille actuelle:
Zoomé x3:
La sortie est un PBM de type P1, selon l'exemple du défi. C'était un défi amusant.
la source
Ruby 1.9, 346 octets (code 122 + données 224 octets)
Voici le résultat:
(C'est bien, non?)
La police a été générée par
figlet -f banner -w 1000 $LETTERS
et ce script .Courez avec
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.Le script génère toutes les lignes et les imprime simplement.
Voici un hexdump (utilisation
xxd -r
):Il faut 93 octets de code lors de l'utilisation de goruby:
L'utilisation de ZLib réduit la taille des données à 142 octets au lieu de 224, mais ajoute 43 octets dans le code, donc 307 octets:
Ce qui donne un total de 268 lors de l'utilisation de goruby:
la source
Java
862826:Voici une approche différente. Je pense que «awt» ne compte pas comme une bibliothèque externe.
Et non golfé:
Robot est la façon curieuse de Java d'appeler getPixel. Je crée une étiquette avec l'alphabet et mesure où se trouve un pixel pour chaque lettre.
Dans la méthode de peinture,
int py = (y < 3) ? y : y +1;
et(8*a+x+17+x/4, py+81)
c'est la manière compliquée, pour ajuster la position dans la police. Huuuh! sinon, il faudrait 9 lignes, et toutes les 4 lettres, il y a un pixel supplémentaire horizontalement. Les essais et les erreurs m'ont amené à cette solution.Ensuite, l'en-tête du PBM est écrit, et chaque ligne du message. Le message est transmis comme titre du cadre.
C'est ça. Pas le code le plus court, mais aucune peinture de police manuelle n'était nécessaire.
Peut-être qu'il pourrait être plus court dans BeanShell ou Scala.
Et maintenant - à quoi ça ressemble?
Plusieurs zooms appliqués:
Sans zoom:
Non pas que le nombre de caractères soit le nombre de caractères de la solution Perl mélangés.
(Il a joué un peu plus au golf. Il a rendu le robot statique, ce qui évite une déclaration d'exception.)
la source
eog
(Eye of Gnome) et une capture d'écran. Je vais télécharger une version non mise à l'échellejpg
; votre navigateur utilise peut-être une interpolation du voisin le plus proche :).C ++ TROP GRAND POUR GAGNER
J'ai écrit un programme de dessin PPM complet en C ++, avec ma propre police bitmap. Même en supprimant toutes les fonctions non nécessaires, c'est toujours énorme par rapport aux réponses ici en raison de la définition de la police.
Quoi qu'il en soit, voici la sortie pour HELLO WORLD:
Et le code:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Si vous êtes intéressé, la bibliothèque PPMDraw complète est ici :
la source
SmileBASIC, 231 octets
Chaque caractère ne contient que 2 motifs de lignes différents, choisis dans une "palette" de 8 combinaisons. Les données de chaque symbole sont stockées dans 1 octet, la palette étant stockée séparément.
la source