En utilisant Algodoo et Paint, j'ai créé ces six images monochromes 300 × 300 de quatre formes pratiques:
Cette classe d'images a les propriétés suivantes:
- Ils ont toujours une résolution de 300 × 300 pixels, monochromes (noir et blanc uniquement) et ont exactement quatre régions blanches correspondant à un carré, un cercle, un triangle et un engrenage.
- Les formes ne se chevauchent ni ne se touchent jamais, pas plus qu'elles ne touchent le bord de l'image ou ne sortent du cadre.
- Les formes ont toujours la même taille, mais elles peuvent être pivotées et positionnées de n’importe quelle manière.
(Les formes ont également des surfaces égales, bien que, si elles sont tramées de la sorte, leur nombre de pixels ne sera probablement pas exactement équivalent.)
Défi
Ecrivez le programme ou la fonction la plus courte possible qui prend le nom de fichier d'une telle image et transforme tous les pixels blancs ...
- rouge
(255, 0, 0)
si elles sont dans le carré. - bleu
(0, 0, 255)
s'ils sont dans le cercle. - vert
(0, 255, 0)
si elles sont dans le triangle. - jaune
(255, 255, 0)
s'ils sont dans l'engrenage.
par exemple
Détails
Votre programme devrait fonctionner efficacement pour toutes les images d'entrée possibles. (Seules les images monochromatiques 300 × 300 valides seront entrées.) Les six images que j'ai fournies ne sont que des exemples. Vous ne pouvez pas coder en dur leur sortie dans votre programme.
Vous ne pouvez pas utiliser de bibliothèques ou de fonctions de vision par ordinateur, intégrées ou externes. Le but est de faire cela en utilisant vos propres opérations au niveau des pixels. Vous pouvez utiliser des bibliothèques d’images qui vous permettent simplement d’ouvrir et de modifier des images (par exemple, PIL pour Python).
Vous pouvez utiliser n'importe quel format de fichier d'image commun sans perte pour les entrées et les sorties, tant que vous vous en tenez au schéma de couleurs.
Vous pouvez prendre l'image nomfichier en tant qu'argument de fonction, depuis stdin ou depuis la ligne de commande. L'image de sortie peut être enregistrée dans un nouveau fichier, le même fichier, ou simplement affichée.
Notation
La soumission avec le moins d'octets gagne. Je peux tester des soumissions avec des images supplémentaires pour déterminer leur validité.
la source
Réponses:
J -
246,224185 octetsC'était amusant!
J'ai réutilisé la pièce de composants connectés que j'ai utilisée pour le défi "Suis-je dans la plus grande pièce" et ai utilisé le rapport entre la distance moyenne et la distance maximale de tous les points au centre de chaque composant. Je me suis décidé pour cela, car il est invariant à la fois en termes d'échelle et de rotation, et apparemment assez bon pour distinguer les formes données. Le classement de cette valeur de bas en haut me donne le cercle d'ordre, l'engrenage, le carré et le triangle utilisés pour permuter la carte de couleurs.
Affiche le résultat en utilisant l'addon viewmap. Aucune boîte à outils utilisée sauf pour la lecture et la sortie de fichier.
La robustesse ne semble pas être une exigence, cela prend 18 octets. 2 autres espaces inutiles, remplacés
&.>
par&>
inratio
et&.:
by&:
dcent pour 2 autres octets.Gain énorme à la fois de brièveté et de performance en
comp
utilisant shifting au lieu decut
(;.
). De cette façon, l'image est répliquée et décalée dans les 8 directions au lieu de la numériser avec une fenêtre 3x3.La
id
fonction était ridiculement complexe pour ce qu'elle devait faire. Désormais, il attribue les identifiants aux pixels des objets en multipliant l'image par un tableau de nombres uniques, ce qui permet de définir la glycémie à zéro.Code un peu plus expliqué:
Celui-ci est un peu long à expliquer en détail, mais fera s'il y a un intérêt.
la source
Mathematica,
459392 octetsUngolfed:
Je pourrais économiser 6 octets de plus en me transformant
m=1.Mean@a;m=#-m&/@a;
enm=#-Mean@a&/@a;
, mais cela accélère considérablement le temps d'exécution, ce qui est gênant pour les tests. (Notez qu'il s'agit de deux optimisations: extraire le calcul de laMean@a
boucle et utiliser des types symboliques exacts au lieu de nombres à virgule flottante. Il est intéressant de noter que l'utilisation de types exacts est beaucoup plus importante que le calcul de la moyenne à chaque itération.)C'est donc l'approche numéro trois:
Maintenant, pour tous les pixels de la forme, traçons la distance de l'angle vs à ce centre:
Le triangle a 3 maxima clairs, le carré 4, l’engrenage 16 et le cercle des tonnes, en raison des fluctuations de repliement autour du rayon constant.
150
est le maximum.Pour mémoire, si j'utilise l'idée d'Ell et que je trie simplement les régions en fonction de la distance la plus grande entre un pixel et le centre, je peux le faire en 342 octets:
Mais je n’ai pas l’intention de rivaliser avec cela, tant que tout le monde utilise ses propres algorithmes originaux, au lieu de jouer avec ceux des autres.
la source
Java,
1204113210871076Juste pour me prouver que je peux le faire.
J'ai inclus les importations juste à côté des déclarations de fonction; ceux-ci devraient être en dehors de la classe pour que cela fonctionne:
Ungolfed (et runnable; c'est-à-dire ajouté)
Cela fonctionne en itérant sur chaque pixel de l'image et en saturant chaque fois que nous atteignons un "trou". Nous ajoutons chaque résultat d'inondation en tant que
Set<Point>
aSet
. Ensuite, nous déterminons quelle forme est laquelle. Ceci est fait en regardant le nombre de pixels limites de la forme. J'ai défini la limite comme un chevalier qui s'éloigne d'une tuile noire, car cela resterait plus constant entre les rotations et autres. Lorsque nous faisons cela, il devient clair que les formes peuvent être triées selon cette valeur: cercle, carré, triangle, engrenage. Donc, je trie et règle tous les pixels de cette forme à la bonne couleur.Notez que l'image que je suis en train d'écrire n'est pas extraite directement du fichier, car si je le faisais, Java traiterait l'image en noir et blanc et le remplissage en couleurs ne fonctionnerait pas. Je dois donc créer ma propre image avec
TYPE_INT_RGB
(ce qui est1
). Notez également que l'image sur laquelle je travaille est302
par302
; ceci afin que l'algorithme de distance de Knight n'ait pas à s'inquiéter d'essayer de lire en dehors des limites de l'image. Je résous cette différence de taille en appelanti.getSubImage(1,1,300,300)
. Remarque: j'ai peut-être oublié de résoudre ce problème lorsque j'ai téléchargé les images. Dans ce cas, les images font 2 pixels de trop, mais à part cela, elles doivent être correctes.La fonction écrasera le fichier dont le chemin est passé. Résultats:
la source
Python,
571 567528 octetsÀ l'instar de la solution de Quincunx, elle commence par remplir chaque forme d'indice compris entre 1 et 4. Elle détermine ensuite l'identité des formes par le rayon de leur cercle de délimitation. Une palette de couleurs est construite en conséquence et l'image est enregistrée en tant qu'image couleur indexée.
EDIT: Manqué le fait que les formes sont garantis pour ne pas toucher la bordure de l'image. C'est plus court alors!
Prend un nom de fichier d'entrée sur la ligne de commande et écrit la sortie dans
o.png
.la source
Mathematica 225
Mise à jour :
Le PO a décidé que cette approche utilisait des fonctions de vision par ordinateur, elle n'était donc plus dans la course. Je vais le laisser posté cependant. Peut-être que quelqu'un le trouvera intéressant.
ImageData
renvoie l'image sous forme de matrice de 0 et de 1.Flatten
convertit cette matrice en liste.Morphological Components
trouve les 4 groupes de pixels et attribue un entier distinct, 1, 2, 3, 4 à chaque pixel en fonction du groupe. 0 est réservé pour le fond (noir).ComponentMeasurements
teste la circularité des grappes.Du plus au moins circulaire sera toujours: le cercle, le carré, le triangle et la vitesse.
ReplacePart
remplace chaque entier composant par la couleur RVB correspondante, en utilisant le tri de circularité.Partition...Dimensions[m][[2]]
prend la liste des couleurs de pixels et renvoie une matrice aux mêmes dimensions que l'image d'entrée.Image
convertit la matrice de couleurs de pixels en une image colorée.la source
f@i_:=Image[#/.Append[Thread[Ordering[Last/@ComponentMeasurements[#,"Circularity"]]->{Yellow,Green,Red,Blue}],0->Black]]&@MorphologicalComponents@i
{RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1], RGBColor[1, 1, 0]}
inactives:, où 1 correspond à 255. Aucune bibliothèque n'a été utilisée.MorphologicalComponents
satisfait ou non à vos règles. Une fois que l’on sait à quel groupe appartient chaque pixel, il existe de nombreuses façons, dont un nombre brut de pixels, de déterminer quel chiffre correspond à quel chiffre.(255,0,22)
lorsque je vérifie dans Paint). Je n'ai pas Mathematica, donc je ne peux pas courir pour m'en assurer.Mathematica,
354345314291288Toujours jouer au golf, pourrait être raccourci de quelques personnages supplémentaires, mais les performances deviennent insupportables. Utilise la variance pour identifier des formes:
Avec espacement:
Essai:
Ici, c'est complètement non-golfé. Va ajouter des explications plus tard:
la source
Python,
579577554514502501 octetsPour chaque forme, la remplit, puis calcule la distance entre le centre de gravité et le point le plus éloigné.
ensuite, la surface réelle de la forme est comparée à la surface d'un triangle, d'un carré, d'un disque ou d'une roue qui aurait la même taille.
la source
C # 1086 octets
Encore une autre solution, pour l’information car il n’existe pas de version C # ici. Comme Quincunx, je voulais prouver que je pouvais le faire et que son approche en Java n’était guère différente.
Il accepte tous les formats d'image.
On peut probablement réduire quelques caractères en supprimant tous les éléments statiques et en créant une instance de Program.
Version lisible:
Golfé:
la source