Compter le nombre de côtés sur un polygone
Le robot de comptage des polygones a décidé de parcourir le monde sans le dire à personne auparavant, mais il est crucial que le processus de comptage des polygones ne soit pas arrêté trop longtemps. Vous avez donc la tâche suivante: Étant donné une image en noir et blanc d'un polygone, votre programme / functoin devrait retourner le nombre de côtés.
Le programme sera alimenté sur un ancien ordinateur à cartes perforées, et comme les cartes perforées sont très chères de nos jours, il vaut mieux essayer de rendre votre programme aussi court que possible.
Les bords font au moins 10 pixels de long, et les angles formés par deux bords adjoints sont d'au moins 10 ° mais pas plus de 170 ° (ou encore plus de 190 °). Le polygone est complètement contenu dans l'image, et le polygone ainsi que son complément sont connectés (il n'y a pas d'îles isolées), donc cette entrée ne serait pas valide:
Notation
Il s'agit de codegolf, ce qui signifie que la soumission la plus courte en octets gagne, votre soumission doit trouver le nombre d'arêtes correct pour chaque cas de test. (Et la soumission devrait également fonctionner pour d'autres cas, l'optimisation uniquement pour ces cas de test n'est pas autorisée.)
Si vous souhaitez soumettre une solution qui ne trouve pas le numéro correct à chaque fois, vous pouvez également le soumettre, mais elle sera classée derrière toutes les soumissions qui fonctionnent mieux.
Veuillez inclure le nombre total dans le titre de votre soumission. (L'erreur totale est la somme des différences absolues entre le nombre réel de côtés et chaque sortie).
Réponses:
Python 2 + PIL, pas d'erreur,
313307 octetsPrend un nom de fichier image sur la ligne de commande et imprime le résultat sur STDOUT.
Donne le résultat correct pour tous les tests et n = 28 pour le cercle.
Explication
L'algorithme fonctionne en marchant le long du périmètre du polygone et en comptant le nombre de sommets rencontrés (détectés comme des changements de direction). Nous partons du pixel le plus éloigné de l'origine,
o
qui est garanti d'être un sommet, et donc d'être adjacent à un bord (c'est-à-dire une frontière entre un pixel de premier plan et un pixel d'arrière-plan). Nous gardons une trace de notre position,p
du sommet le plus récentv
et du "point de contrôle" le plus récentq
, qui sont tous initialement égaux ào
. Nous suivons également la direction du bordd
,, par rapport au pixel actuel;d
pointe d'abord vers l'est, ce qui est une direction sûre, car nous savons qu'il y a un bord à l'est deo
, sinon il ne serait pas le plus éloigné de l'origine. Nous nous déplaçons le long du bord, dans une direction perpendiculaire àd
, telle qu'elled
pointe vers notre gauche, c'est-à-dire dans le sens horaire. Chaque fois que nous «tombons du bord», c'est-à-dire dans toute situation oùp
est en dehors du polygone, ou où le pixel à notre gauche (c'est-à-dire dans la direction ded
) est à l'intérieur du polygone, nous nous ajustonsp
et end
conséquence avant de reprendre.Chaque fois que la distance entre
p
et le dernier point de contrôle,q
devient supérieure à 5, nous essayons de déterminer si nous avons dépassé un sommet entreq
etp
: Nous comparons l'angle entrevq
(c'est-à-dire le vecteur dev
àq
), qui est la direction générale de la côté du polygone que nous marchions lorsque nous avons atteint le dernier point de contrôle, etqp
, le déplacement entre le dernier point de contrôle et la position actuelle. Si l'angle est supérieur à environ 10 °, nous concluons que nous marchons le long d'un côté différent du polygone, augmentons le nombre de sommets et définissonsv
le sommet actuel surp
. À chaque point de contrôle, que nous ayons détecté ou non un sommet, nous mettons à jourq
, le dernier point de contrôle,p
. Nous continuons de cette façon jusqu'à ce que nous arrivions auo
point de départ et retournions le nombre de sommets trouvés (notez que le nombre de sommets est initialement de 1, car le point de départo
est lui-même un sommet).Les images ci-dessous montrent les sommets détectés. Notez que la prise
p
, la position actuelle à chaque point de contrôle, comme la position du nouveau sommet n'est pas optimale, car le sommet réel est probablement quelque part entre le dernier point de contrôle,,q
etp
, le long du périmètre. Comme vous pouvez le voir, tous les sommets autres que le premier (généralement le sommet en bas à droite) sont un peu décalés. Corriger cela coûterait plus d'octets, mais cela semble fonctionner assez bien tel quel. Cela étant dit, il est un peu difficile de ne pas surcharger avec seulement quatre cas de test.la source
o
, l'autre extrémité ne serait-elle pas encore plus éloignée de l'origine?o
est le pixel de premier plan le plus éloigné de l'origine, donc le pixel à son est doit être un pixel d'arrière-plan, d'où nous disons qu'il y a un bord à l'est deo
.