Après avoir passé un certain temps sur Stack Exchange, je peux reconnaître la plupart des sites de Hot Network Questions à leur petite icône (qui est également leur favicon ), mais certainement pas tous. Écrivons un programme qui peut! Vous devez écrire le code qui détermine le site, étant donné l’un des 132 favicons (actuellement), y compris Stack Overflow en japonais (qui est toujours en version bêta privée):
J'ai téléchargé un fichier ZIP contenant toutes ces images au format PNG sur GitHub . Cliquez sur le bouton "Raw" pour le télécharger. L'ordre des icônes ci-dessus est l'ordre alphabétique des noms de fichiers dans le zip.
Les noms de site correspondants (dans cet ordre) sont:
Remarques:
- J'ai supprimé les éléments
®
deLEGO® Answers
etExpressionEngine® Answers
, afin que vous n'ayez pas à vous soucier de Unicode. - J'ai utilisé les noms anglais pour les débordements de pile en japonais et en portugais pour la même raison.
- Les icônes des sciences de la Terre et de la langue espagnole sont indiscernables. Par conséquent, étant donné l’une de ces icônes, votre code peut renvoyer l’un ou l’autre de ces sites (de votre choix). Il en va de même pour Magento et les arts martiaux .
Règles
Vous pouvez écrire un programme ou une fonction qui
- reçoit le nom de fichier (local) de l'image via STDIN, un argument de ligne de commande ou une fonction, ou reçoit le contenu du fichier image via STDIN
- renvoie ou imprime à STDOUT le nom du site, comme indiqué ci-dessus.
Votre code doit reconnaître correctement les 132 sites (à l'exception de celle mentionnée ci-dessus).
Vous ne pouvez faire aucune hypothèse sur le nom du fichier (comme cela s'appelle codegolf.png
). Vous pouvez supposer que l’image a des dimensions de 16x16 et qu’il s'agira bien d’une des 132 images ci-dessus. Les images ci-dessus sont toutes des images PNG, mais vous pouvez utiliser n’importe quel autre format graphique raster, mais vous devrez convertir les images vous-même. Vous ne devez faire aucune hypothèse sur le flux d'octets réel du fichier image, mis à part le fait que c'est une image valide dans le format que vous avez choisi. En particulier, s'il existe plusieurs manières de coder la même image dans votre format (par exemple, en ajoutant des champs non pertinents à la section d'en-tête), votre code doit fonctionner pour toutes. En bref, votre code ne doit s’appuyer que sur les valeurs de pixel elles-mêmes, sans aucun détail sur le fichier l’encodant.
Comme d'habitude, vous ne pouvez extraire aucune donnée d'Internet. Vous devez déterminer le site à partir de l'image seule.
Vous pouvez utiliser des fonctions intégrées ou tierces pour lire le fichier image et obtenir une liste de valeurs de couleur, mais vous ne devez utiliser aucune autre fonction de traitement d'image existante.
C'est le code de golf, donc la réponse la plus courte (en octets) gagne.
la source
pngcrush
ils n'existeront pas.Réponses:
Python 3.x + Oreiller,
230118941878 octetsL'idée est de hacher l'image et de trouver la chaîne correspondante dans un dictionnaire (comme pour les autres réponses).
Le code de la clé est le suivant:
Nous ouvrons le fichier et le convertissons ensuite en chaîne de 1024 octets de valeurs RGBA. Avec un peu d'expérimentation, nous constatons que la somme de contrôle ADLER-32 de chaque sixième octet de cette chaîne d'octets est unique pour ces 132 images. Et puis des tests supplémentaires montrent que, en prenant le module de 2003 de la somme de contrôle, on obtient le plus petit dictionnaire.
Le dictionnaire original ressemble à:
Nous avons remarqué que tous les noms de sites ne contiennent pas de chiffres. Nous pourrions donc concaténer le dictionnaire entier en une seule chaîne:
Et utilisez ensuite l'expression régulière, par exemple,
1969(\D+)
pour extraire le nom du site. Cette énorme chaîne est ensuite compressée pour économiser de l'espace (laissez le moteur de compression remarquer les multiples occurrences de "Language"), et finalement encodée en base 85.Etant donné qu’elle porte désormais la mention kolmogorov-complex , voici une solution de 2394 octets qui n’utilise pas de compression (la bibliothèque zlib est toujours importée pour adler32).
la source
.tobytes()
récupère les données de pixels (16 × 16 × 4 = 1024), donc il s'appuie sur l'image. Le fichier doit être dans RGBA cependant.C #, 2760 octets
Ma solution n'utilise pas de hachage, elle examine en réalité les pixels individuels de l'image et décide en fonction. J'ai découvert qu'il suffisait d'examiner la composante bleue de l'image modulo 9. L'idée est de scinder à plusieurs reprises en fonction de la valeur de pixel.B% 9, comme suit:
À l'aide d'un script, j'ai généré le programme monstrueux suivant (5197 octets) qui résout le problème à l'aide d'un arbre de décision binaire:
Certaines personnes ont utilisé des fonctions de compression intégrées dans leurs solutions. J'ai créé le mien en écrivant un script qui identifie les sous-chaînes communes et les remplace par des raccourcis à un caractère. Le code est compressé dans la chaîne 2502 bye suivante:
Le dictionnaire nécessaire à la décompression ne contient que 108 octets:
Le dictionnaire utilise des points-virgules comme séparateur et contient des caractères uniques suivis de leur décompression. Donc, pour décompresser, ":" serait d'abord remplacé par "&", puis "<" par "%!", "|" par "ic", et ainsi de suite. La décompression d'une chaîne c peut être exprimée de manière assez concise:
Ensuite, après la décompression, j'utilise un peu de réflexion Black-Magic pour compiler le code à la volée et l'exécuter:
Notez que les exemples utilisés ici pour l'explication diffèrent légèrement de ceux utilisés dans la solution à 2876 octets.
la source
Node.js,
3178313026672608 octetsCalcule le hachage SHA1 des données d'image de chaque fichier et, à l'aide des octets 16 à 19 du condensé hexadécimal, indexe les noms de sites.
En utilisant les octets 12 à 16 du résumé hexadécimal du hachage SHA1 de chaque fichier, indexe les noms de sites. Il peut y avoir une combinaison plus courte utilisant seulement 3 octets du condensé hexadécimal.la source
h="17352368".match(/.{4}/g)
(les 4 caractères de hachage, divisés en un tableau),s="MathOverflow;StackOverflow in Portuguese".split(";")
(noms séparés par un;), puis regroupez le tout à nouveau:t={}h.forEach(function(k,i){t[k]=s[i]})
(donne le même objet que votre code). Il y a 132 points-virgules. Ainsi, même si vous passez à un caractère de 2 octets (OP indique qu'il ne devrait y avoir aucun unicode dans les noms de sites), vous gagnerez de l'espace. En outre, vous pouvez ajouter l'optimisation de @manatwork à cette sauvegarde supplémentaire.split()
s: une seule chaîne du type "1234Site; 5678Other". Ensuite, à supposer qu'il n'y ait pas de conflit entre les fragments de hachage et les noms de sites, un seul lematch()
fera:function $(e){r=require;return"8d4fAcademia;3a6dAndroid Enthusiasts;5caeAnime & Manga;804cAsk Different;bef3Arduino".match(r("crypto").createHash("sha1").update(r("fs").readFileSync(e)).digest("hex").slice(12,16)+"([^;]+)")[1]}
Python 2.7,
19061889 octetsCette solution utilise CRC32 sur les données de pixels pour créer un identifiant unique à la base 95 à 2 chiffres. L'index de l'identifiant est ensuite utilisé pour rechercher la chaîne de réponse.
Le problème était de trouver une combinaison de fonctions de style hachage qui aurait pour résultat 132 (ou 131) étiquettes petites mais uniques. J'ai essayé quelques options avant de choisir celle-ci. Cela semble assez compact.
Le programme utilise Python PIL pour lire les données de pixels du fichier.
Python 2.7 2150 octets
Ceci est une version sans utiliser les bibliothèques de compression ou de codage. La liste d’échange de piles est compressée avec une méthode d’échange simple. Les caractères non utilisés dans le texte:
sont utilisés pour contenir des segments de chaîne communs. Le texte est décompressé avec la
for k,v in [(v[0],v[1:]) for v in K.split('|')]:T=T.replace(k,v)
ligne. La table d'indexation à deux caractères est la même que dans le programme ci-dessus.la source
C #, 2672 octets
La table (chaîne) d'étiquettes et de hachages SHA partiels est compressée pour économiser quelques octets. Le dictionnaire original ressemble à:
la source
var
devrait protéger quelques octets. 2) Quel est avec le constructeur de chaînes? Je ne le vois pas utilisé. 3)StreamReader.ReadToEnd
pourrait aider un peu aussi.