Python 2 + PIL, hata yok, 313 307 bayt
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
Komut satırında bir görüntü dosyası adı alır ve sonucu STDOUT'a yazdırır.
Tüm testler için doğru sonucu ve daire için n = 28 değerini verir.
açıklama
Algoritma, çokgenin çevresi boyunca yürüyerek ve karşılaşılan köşe noktalarının sayısını (yön değişiklikleri olarak algılanır) sayarak çalışır. Köşe noktası o
olduğu ve bu nedenle bir kenara bitişik (yani, ön plan pikseli ile arka plan pikseli arasındaki bir sınır) olduğu garanti edilen, başlangıç noktasından en uzak pikselden başlıyoruz . Başlangıçta hepsi eşit olan konumumuzu, p
en son tepe noktasını v
ve en son "kontrol noktasını" takip q
ediyoruz o
. Ayrıca d
, mevcut piksele göre kenarın yönünü de izleriz; d
başlangıçta doğuyu gösterir, bu güvenli bir yön, çünkü doğuda bir kenar olduğunu biliyoruzo
ya da başka bir deyişle, başlangıç noktasından en uzakta olmazdı. Kenar boyunca, solumuzu gösterecek şekilde , yani saat yönünde hareket d
edecek d
şekilde hareket ediyoruz. "Kenardan düştüğümüzde", yani p
çokgenin dışında veya solumuzdaki pikselin (yani yönünde d
) çokgenin içinde olduğu herhangi bir durumda , ayarlamaya p
ve d
buna uygun olarak devam etmeden önce.
Her zaman arasındaki mesafe p
ve geçen kapısı olan q
, 5'ten büyür, biz arasında bir köşe geçti olup olmadığını belirlemeye çalışır q
ve p
: Biz arasındaki açıyı karşılaştırmak vq
(yani gelen vektör v
için q
) genel yönü olduğunu, son kontrol noktasına ulaştığımızda yürüdüğümüz çokgenin bir tarafı qp
ve son kontrol noktası ile mevcut konum arasındaki yer değiştirme. Açı yaklaşık 10 ° 'den büyükse, çokgenin farklı bir kenarı boyunca yürüdüğümüz, tepe noktası sayısını artırdığımız v
ve mevcut tepe noktasını olarak ayarladığımız sonucuna varıyoruz p
. Her kontrol noktasında, bir tepe noktası tespit edip etmememizden bağımsız olarak q
, son kontrol noktasınıp
. Bu o
noktaya, başlangıç noktasına dönene ve bulunan köşe sayısını döndürene kadar devam ediyoruz (başlangıç noktasından beri tepe noktası sayısının başlangıçta 1 olduğunu unutmayın o
, kendisi bir tepe noktasıdır .)
Aşağıdaki resimler algılanan köşeleri göstermektedir. Alarak geldiğini hatırlatırız p
gerçek tepe muhtemelen bir yerlerde son kontrol noktasında arasındadır, çünkü yeni tepe noktası konumunda olarak, her kontrol noktasında, mevcut konumu, optimum değildir q
ve p
çevre boyunca. Gördüğünüz gibi, ilkinden başka tüm köşeler (genellikle sağ alt köşe) biraz kapalı. Bunu düzeltmek daha fazla bayta mal olabilir, ancak bu olduğu gibi yeterince iyi çalışıyor gibi görünüyor. Bununla birlikte, sadece dört test vakasına uymamak biraz zor.