Le défi du golf est d'encoder et de compresser l'image suivante dans un fichier source.
Pour ce faire , vous devez écrire 3 fonctions: red
, green
et blue
qui acceptent x / y de l'image et renvoie la valeur de pixel R / G / B correspondant entre 0-255.
Voici le code de test C / C ++:
#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));
}
Et la sortie: http://pastebin.com/A770ckxL (vous pouvez l'utiliser pour générer vos données d'image)
Règles et détails:
- C'est un golf
- Seul votre code / fichier est joué - le code de test est séparé
- Le jeu de caractères utilisé est ASCII, mais les caractères de contrôle dans les chaînes ne peuvent être utilisés qu'en cas d'échappement (comme '\ n' et '\ r', etc.)
- Tout doit être contenu à l'intérieur de la source - aucun chargement de fichier
- Votre sortie doit correspondre à l'exemple de sortie. Cela signifie une compression sans perte.
Langues:
Le problème a été écrit en pensant à C / C ++, mais je supprime ces restrictions. Cela dit, je recommanderai toujours de les utiliser.
Réponses:
C,
796 754 712 703 692 685 682 670 666 662 656648 car.Journal des modifications:
return
au#define
, remplaçantif
par des?
instructions (merci @FUZxxl), supprimantint
de la liste des paramètres des fonctions.#define
p[]
eth[]
quelques?:
améliorations supplémentairesb
donci
est plus nécessaire.m=b
au lieu dem=11
etn<2e3
au lieu dei<356
- ceux-ci sont proches d'une corruption de comportement / mémoire non définie, mais il semble que j'ai de la chance :)k
est maintenant (32,16,8,4,2,1,0) au lieu de (5,4,3,2,1,0). Gotcha, DC;)p[]
eth[]
, convertih[]
enchar*
- awwww, il y a un minou endormi dedans^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, nous pouvons donc mapper sur 64-127 au lieu de 0-63 et nous n'avons plus besoin d'index de bitsk
. Merci @Piotr Tarsa . Remplacé?:
(extension GCC) par||
. Merci @JamesBp[]
)L'image est convertie en une chaîne de type Base64 (ASCII 37-100), en utilisant le codage Huffman pour coder les couleurs 0-9 en utilisant 3-6 bits et une couleur spéciale 10 (le pixel est le même que le précédent) en utilisant seulement 1 bit.
Copié deux choses de la réponse de bunnit,
#define
et l'image entière étant décodée complètement à chaque appel dered
/green
/blue
. Il y a de la place pour des améliorations supplémentaires, alors attendez-vous à quelques mises à jour :) Je ne suis pas sûr de la conformité du code, j'ai utilisé GCC 4.6.1 pour compiler et tester.En ce qui concerne la compression, je pense que le codage arithmétique serait utile car la distribution est assez asymétrique, mais peut-être que la surcharge de code serait trop lourde dans ce cas. LZW devrait également faire un très bon travail. Les couleurs sont assez locales, donc le codage adaptatif pourrait être une idée.
Version 754 caractères plus lisible avec quelques commentaires:
la source
int
des listes de paramètres pour supprimer quelques octets supplémentaires.m=m>9?c[n-1]:m;
pourif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
pourquoi pask>=0?:(j=b[i++]-37,k=5);
? (Ce code utilise une extension C de gcc,x=a?:b
est le même quex=a?a:b
, à la différencered(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 caractères)Puisque ce défi est désormais ouvert à tous, pourquoi pas! C'est la route de codage familière zlib -> base64, donc je m'en excuse. Espérons qu'une entrée avec un semblant d'ingéniosité sera plus courte!
Voici un extrait de test analogue à l'original:
la source
C ++, 631 caractères; C - 613
Un codeur mtf unaire base-92, C ++, 631 caractères:
Et la version C ci-dessus (613 caractères):
Juste pour inclure une entrée avec des données de base 95 et un codage arithmétique + un modèle statistique adaptatif.
Le code de schnaader utilise environ 438 caractères pour les données et le mien seulement 318 (311 sans masquage).
Mais comme prévu, le codage arithmétique est trop compliqué pour un petit échantillon comme celui-ci.
(Il s'agit de 844 caractères)
Tests (à partir d'une version antérieure de la base 96):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
D'une manière ou d'une autre, SO mange des codes 7F, j'ai donc dû le mettre à jour en base = 95
la source
C ++ -
15251004964 caractèresCréation d'un tableau z qui stocke toutes les couleurs possibles sous la forme d'un seul entier (r << 16 | g << 8 | b). Création d'un tableau d qui stocke {montant, valeur}, la valeur est la position dans le tableau z, le montant est le nombre de pixels consécutifs avec cette valeur (c'est-à-dire 3,0, signifie que colout t [0] apparaît les 3 suivants pixels. Le tableau réel de pixels (c) est ensuite calculé chaque fois que le rouge est appelé. La valeur dans le tableau est ensuite décalée vers la droite et modifiée si nécessaire pour obtenir le composant correct.
Je pourrais probablement enregistrer quelques caractères de plus (~ 50) en retirant plus de modèles du tableau tel que défini.Edit 1 - a changé le tableau d pour un tableau char avec chaque valeur décalée de 48, ce qui signifie que je peux le représenter comme une chaîne enregistrant une charge de virgules.
Edit 2 - Suppression d'une plus grande partie des fonctions dans l'instruction define.
la source
int
(int f(int x,int y)
devient ainsif(x,y)
.Javascript,
696694 caractèresMerci à schnaader pour 696 -> 694.
J'ai figuré un format de codage différent, qui est essentiellement un codage de longueur avec une table de recherche de couleurs. Cela fonctionne assez bien, car il y a moins de 16 couleurs et elles apparaissent moins de 16 fois de suite; de sorte que chaque définition de pixel, y compris la longueur, tient dans un octet. J'ai mis la couleur dans la partie haute de l'octet et le nombre dans la partie basse.
Au final, la chaîne base64 s'est avérée plus longue que ce à quoi je m'attendais (472 caractères), mais le programme de décodage est vraiment court.
Remarque: J'ai divisé le code pour avoir un peu de lisibilité. Il doit être sur une seule ligne pour fonctionner.
Code de test:
Je pense que l'exemple de résultat est en fait la sortie de rouge, vert, bleu (pas rouge, bleu, vert comme dans le code de test d'origine); ça marche pour moi comme ça de toute façon.
la source
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
- cela enregistre 1 caractère et correspond à l'ordre GBR au lieu de RGB.C ++, 1357 caractères
Désobfusqué un peu:
C
contient les valeurs RVB pour les dix couleurs distinctes de l'image.E
contient les données de l'image, où chaque élémentE[i]
code à la fois un nombre de répétitionsE[i]/10
et un indice de couleurE[i]%10
.la source
int red(x,y){R Q(x+32*y)[0]}(only
# define`return
), vous pourrez peut-être raser plus de caractères.Python 3 (589 caractères)
Code de test
Basé sur la solution de Dillon Cower
la source
PHP (5,4) - 822
J'ai fait cela délibérément en n'utilisant aucune des fonctions de compression intégrées . Cette solution n'est pas terminée, je ne sais pas si j'ai abandonné, je peux voir des points à améliorer mais je ne trouve pas le temps / la volonté de refactoriser le tout pour le moment, donc je poste ce que je ont jusqu'à présent.
Newlines + commentaires à supprimer pour 822 octets.
Talon de test:
La compression des données d'image elle-même est assez bonne, mais les fonctions de récupération des valeurs RVB occupent 1/4 du code.
J'utilise un mécanisme d'encodage personnalisé en base70 +.
Les données d'image codées font référence à l'index de tableau d'un RLE, qui à son tour indexe le tableau de couleurs. Je ne sais pas combien de frais généraux cela ajoute ou soustrait par rapport directement aux couleurs.
Sinon il y a 10 couleurs (0 à 9), les RLE sont stockés sous
run_length * 10 + colour_index
. Donner une plage d'encodages entre 10 et 145 sans expérimenter avec des optimisations basées sur l'ordre des couleurs. (c'est-à-dire que je pourrais faire la plage 19 à 140 en déplaçant les couleurs 0 à 5, 5 à 9 et 9 à 0 - mais cela peut avoir d'autres effets d'entraînement)Une réponse précédente indique que leurs données codées sont de 472 octets. Mes données d'image codées sont de 352 octets, mais la carte RLE / couleur intermédiaire (qui n'est pas codée en binaire) est de 129 octets supplémentaires, ce qui met le total à 481. (ainsi que des frais généraux supplémentaires pour joindre les deux). Cependant, je soupçonne que ma méthode pourrait être mieux adaptée aux images plus grandes.
FAIRE:
global
est une chienne, mais ne peut pas accéder aux index des caractères sur les constantes.la source
C (gcc) , 602 octets
Essayez-le en ligne!
Fatigué
la source