Python 2 + PIL, nessun errore, 313 307 byte
from Image import*
I=open(sys.argv[1])
w,h=I.size;D=I.getdata()
B={i%w+i/w*1j for i in range(w*h)if D[i]!=D[0]}
n=d=1;o=v=q=p=max(B,key=abs)
while p-w:
p+=d*1j;e=2*({p}<B)+({p+d}<B)
if e!=2:e%=2;d*=1j-e*2j;p-=d/1j**e
if abs(p-q)>5:
t=(q-v)*(p-q).conjugate();q=p;w=o
if.98*abs(t)>t.real:n+=1;v=p
print n
Prende il nome di un file immagine dalla riga di comando e stampa il risultato su STDOUT.
Fornisce il risultato corretto per tutti i test e n = 28 per il cerchio.
Spiegazione
L'algoritmo funziona camminando lungo il perimetro del poligono e contando il numero di vertici rilevati (rilevati come cambiamenti di direzione). Iniziamo dal pixel più lontano dall'origine, oche è garantito per essere un vertice, e quindi, per essere adiacente ad un bordo (cioè un confine tra un pixel di primo piano e un pixel di sfondo). Teniamo traccia della nostra posizione, pil vertice più recente ve il "checkpoint" più recente q, che inizialmente sono tutti uguali o. Teniamo anche traccia della direzione del bordo d, rispetto al pixel corrente; dinizialmente punta ad est, che è una direzione sicura, poiché sappiamo che c'è un bordo ad est dio, altrimenti non sarebbe più lontano dall'origine. Ci muoviamo lungo il bordo, in una direzione perpendicolare a d, tale che dpunta alla nostra sinistra, cioè in senso orario. Ogni volta che "cadiamo dal bordo", cioè in qualsiasi situazione pal di fuori del poligono o in cui il pixel alla nostra sinistra (cioè nella direzione di d) si trova all'interno del poligono, ci adeguiamo pe di dconseguenza prima di riprendere.
Ogni volta che la distanza tra pe l'ultimo punto di controllo, qdiventa maggiore di 5, proviamo a determinare se abbiamo superato un vertice tra qe p: confrontiamo l'angolo tra vq(cioè il vettore da va q), che è la direzione generale del lato del poligono che stavamo percorrendo quando abbiamo raggiunto l'ultimo checkpoint e qplo spostamento tra l'ultimo checkpoint e la posizione corrente. Se l'angolo è maggiore di circa 10 °, concludiamo che stiamo camminando lungo un lato diverso del poligono, aumentiamo il conteggio dei vertici e impostiamo vil vertice corrente su p. Ad ogni checkpoint, indipendentemente dal fatto che abbiamo rilevato un vertice o meno, aggiorniamo q, l'ultimo checkpoint, ap. Continuiamo in questo modo fino a quando non arriviamo al opunto di partenza e restituiamo il numero di vertici trovati (si noti che il conteggio dei vertici è inizialmente 1, poiché il punto di partenza o, è esso stesso un vertice).
Le immagini seguenti mostrano i vertici rilevati. Si noti che prendendo p, la posizione corrente in ciascun checkpoint, poiché la posizione del nuovo vertice non è ottimale, poiché il vertice reale è probabilmente da qualche parte tra l'ultimo checkpoint qe p, lungo il perimetro. Come puoi vedere, tutti i vertici diversi dal primo (generalmente il vertice in basso a destra) sono un po 'spenti. La correzione di questo costerebbe più byte, ma sembra funzionare abbastanza bene così com'è. Detto questo, è un po 'difficile non esagerare con solo quattro casi di test.
