다각형의 변 수를 센다


18

다각형의 변 수를 센다

다각형 측 카운팅 로봇은 이전에 아무에게도 알리지 않고 세계를 여행하기로 결정했지만 다각형 카운팅 프로세스가 너무 오래 멈추지 않는 것이 중요합니다. 따라서 다음과 같은 작업이 있습니다. 다각형의 흑백 이미지가 제공되면 프로그램 / 펑크 인은 변의 개수를 반환해야합니다.

이 프로그램은 오래된 펀치 카드 컴퓨터에 공급 될 것이며 오늘날 펀치 카드는 매우 비싸므로 가능한 짧게 프로그램을 작성하는 것이 좋습니다.

가장자리는 적어도 10 픽셀 길이이고, 인접한 두 가장자리에 의해 형성된 각도는 10도 이상 170도 이하 (또는 190 도보 다 크지 않음)이다. 다각형은 이미지 내에 완전히 포함되어 있으며 다각형뿐만 아니라 보완 요소도 연결되어 있습니다 (격리 된 섬이 없음).이 입력은 유효 하지 않습니다.

여기에 이미지 설명을 입력하십시오

채점

이것은 codegolf입니다. 즉, 바이트 단위로 가장 짧은 제출은 승리합니다. 제출할 때마다 모든 테스트 사례에 대해 올바른 수의 모서리를 찾아야합니다. (그리고 제출은 다른 경우에도 적용되어야하며, 해당 테스트 사례에 대한 최적화는 허용되지 않습니다.)

매번 올바른 번호를 찾지 못하는 솔루션을 제출하려면 해당 번호도 제출할 수 있지만 성능이 더 우수한 모든 제출물보다 순위가 높습니다.

제출 제목에 총수를 기재하십시오. (총 오류는 실제 변 수와 각 출력 간의 절대 차이의 합입니다.)

테스트 사례

n = 10

여기에 이미지 설명을 입력하십시오여기에 이미지 설명을 입력하십시오

n = 36

여기에 이미지 설명을 입력하십시오여기에 이미지 설명을 입력하십시오

n = 7

여기에 이미지 설명을 입력하십시오여기에 이미지 설명을 입력하십시오

n = 5

여기에 이미지 설명을 입력하십시오여기에 이미지 설명을 입력하십시오

이것은 호기심으로 테스트 사례가 아닙니다.이 입력에 대해 얼마나 많은 가장자리를 얻습니까?

여기에 이미지 설명을 입력하십시오


테스트 사례에서 170 °보다 큰 각도를 보았습니다. 예를 들어, 별의 모든 "비점"각도 (중심에 더 가까운 각도)입니다.
Doorknob

@Doorknob 170 °보다 작아야하는 작은 각도입니다.
lirtosiast

예, 그러나 다시 190 °보다 큽니다. 이 제한의 요점은 두 인접면을 구별하기 어려운 예를 제거하는 것입니다.
flawr

2
다각형의 내부는 어떤 색입니까?
feersum

1
이 프로그램은 오래된 펀치 카드 컴퓨터에 공급 될 것이며, 오늘날 펀치 카드는 매우 비싸므로 가능한 짧게 프로그램을 작성하는 것이 좋습니다 :-)
Luis Mendo

답변:


12

파이썬 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처음에는 동쪽을 가리 킵니다. 동쪽 방향에는 모서리가 있다는 것을 알기 때문에 안전한 방향입니다.od 입니다.d시계 방향으로 왼쪽을 가리 킵니다. 우리가 "가장자리에서 떨어질 때", 즉 p다각형 외부에 있거나 왼쪽에있는 픽셀 (예 : 방향 d)이 다각형 안에있는 상황에서 우리는 조정 p하고d 다시 시작 따라하기 전에.

때마다 사이의 거리 p와 마지막 체크 포인트, q5보다 큰 도착, 우리는 우리가 사이에 정점에 걸쳐 통과 여부를 결정하려고 q하고 p: 우리 사이의 각도를 비교 vq(즉,에서 벡터 vq)의 기본 방향이다, 마지막 체크 포인트에 도달했을 때 따라 갔던 다각형의 측면, 그리고 qp마지막 체크 포인트와 현재 위치 사이의 변위. 각도가 약 10 °보다 크면 다각형의 다른면을 따라 걷다가 정점 수를 늘리고 v현재 정점을으로 설정 합니다p . 각 체크 포인트에서 정점 감지 여부에 관계없이 업데이트합니다.q 마지막 검사 점을 다음으로 합니다.p. 우리는 o시작점에 다시 도달 하고 발견 된 정점의 수를 반환 할 때까지이 방식으로 계속 진행 합니다 o.

아래 이미지는 감지 된 정점을 보여줍니다. p실제 정점은 아마도 주변을 따라 마지막 체크 포인트와 q, 사이에있을 수 있으므로 새 정점의 위치로 각 검사 점에서 현재 위치 를 취하는 것은 최적이 아닙니다 p. 보시다시피, 첫 번째 정점 이외의 모든 정점 (일반적으로 오른쪽 하단 정점)은 약간 벗어납니다. 이 문제를 해결하려면 더 많은 바이트가 필요하지만 제대로 작동하는 것 같습니다. 그러나 네 가지 테스트 사례만으로 과적 합하지 않는 것은 조금 어렵습니다.

n = 10 n = 36 n = 7 n = 5 원


자세한 설명 감사합니다! 나는 당신의 삽화를 사랑합니다!
flawr

의 동쪽 가장자리가 있다면 o다른 쪽 끝이 원점에서 더 멀지 않습니까?
aditsu

1
@aditsu 나는이 용어가 약간 혼란 스럽다고 생각한다. 우리 는 기하학적 측면 에서 다각형 의 측면 과 래스터 그래픽으로 다각형을 구성하는 픽셀 의 가장자리 에 대해 이야기합니다 . o는 원점에서 가장 먼 전경 픽셀이므로 동쪽의 픽셀은 배경 픽셀이어야합니다. 따라서 동쪽의 가장자리가 있다고 말합니다 o.
Ell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.