Python 2 + PIL, без помилок, 313 307 байт
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
Знімає ім'я файлу зображення в командному рядку та друкує результат на STDOUT.
Дає правильний результат для всіх тестів, а n = 28 для кола.
Пояснення
Алгоритм працює, проходячи по периметру багатокутника і підраховуючи кількість зустрічаються вершин (виявляються як зміни напрямку). Ми починаємо з пікселя, віддаленого від початку, oякий гарантовано є вершиною, а отже, прилягає до краю (тобто межі між пікселем переднього плану та фоновим пікселем). Ми відслідковуємо свою позицію, pостанню вершину vта останню "контрольну точку" q, всі вони спочатку рівні o. Ми також стежимо за напрямком краю d, щодо поточного пікселя; dспочатку вказує на схід, що є безпечним напрямком, оскільки ми знаємо, що є край на схід відo інакше він не був би найдалі від початку. Рухаємось по краю, у напрямку, перпендикулярному доd такого, якийdвказує зліва, тобто за годинниковою стрілкою. Щоразу, коли ми «падаємо з краю», тобто в будь-якій ситуації, де pзнаходиться поза полігоном, або де піксель зліва від нас (тобто у напрямку до d) знаходиться всередині полігону, ми регулюємось pі dвідповідно до відновлення.
Кожен раз, коли відстань між pі останньою контрольною точкою qстає більшою за 5, ми намагаємося визначити, чи ми пройшли вершину між qі p: Ми порівнюємо кут між vq(тобто вектором від vдо q), який є загальним напрямком сторони полігону, по якому ми йшли, коли дійшли до останньої контрольної точки, і . Ми продовжуємо таким чином, поки не повернемось до початкової точки та не повернемо кількість знайдених вершин (зауважте, що кількість вершин спочатку 1, оскільки початкова точка,qp переміщення між останньою контрольною точкою та поточною позицією. Якщо кут більший приблизно на 10 °, то робимо висновок, що ми йдемо по іншій стороні багатокутника, збільшуємо кількість вершин і встановлюємоv поточну вершину на p. На кожній контрольній точці, незалежно від того, виявили ми вершину чи ні, ми оновлюємосьq останню контрольну точку доpoo сама по собі є вершиною).
Зображення нижче показують виявлені вершини. Зауважимо, що прийняття pпоточного положення в кожній контрольній точці як положення нової вершини не є оптимальним, оскільки справжня вершина, ймовірно, знаходиться десь між останньою контрольною точкою q, та pпо периметру. Як бачимо, всі вершини, крім першої (як правило, нижня права вершина) трохи відключені. Виправлення цього коштуватиме більше байтів, але, здається, це працює досить добре. Незважаючи на це, важко не переборщити лише чотири тестові справи.
