파이썬 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
)의 기본 방향이다, 마지막 체크 포인트에 도달했을 때 따라 갔던 다각형의 측면, 그리고 qp
마지막 체크 포인트와 현재 위치 사이의 변위. 각도가 약 10 °보다 크면 다각형의 다른면을 따라 걷다가 정점 수를 늘리고 v
현재 정점을으로 설정 합니다p
. 각 체크 포인트에서 정점 감지 여부에 관계없이 업데이트합니다.q
마지막 검사 점을 다음으로 합니다.p
. 우리는 o
시작점에 다시 도달 하고 발견 된 정점의 수를 반환 할 때까지이 방식으로 계속 진행 합니다 o
.
아래 이미지는 감지 된 정점을 보여줍니다. p
실제 정점은 아마도 주변을 따라 마지막 체크 포인트와 q
, 사이에있을 수 있으므로 새 정점의 위치로 각 검사 점에서 현재 위치 를 취하는 것은 최적이 아닙니다 p
. 보시다시피, 첫 번째 정점 이외의 모든 정점 (일반적으로 오른쪽 하단 정점)은 약간 벗어납니다. 이 문제를 해결하려면 더 많은 바이트가 필요하지만 제대로 작동하는 것 같습니다. 그러나 네 가지 테스트 사례만으로 과적 합하지 않는 것은 조금 어렵습니다.