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
) ซึ่งเป็นทิศทางทั่วไปของ ด้านข้างของรูปหลายเหลี่ยมที่เรากำลังเดินไปเมื่อเราไปถึงด่านสุดท้ายและqp
การกระจัดระหว่างจุดตรวจสุดท้ายกับตำแหน่งปัจจุบัน ถ้ามุมมากกว่าประมาณ 10 องศาเราสรุปว่าเราสามารถเดินกำลังพร้อมด้านที่แตกต่างของรูปหลายเหลี่ยม, เพิ่มจำนวนจุดสุดยอดและชุดv
, p
จุดสุดยอดในปัจจุบันจะ ที่จุดตรวจแต่ละจุดโดยไม่คำนึงว่าเราตรวจพบจุดสุดยอดหรือไม่เราอัปเดตq
จุดตรวจสุดท้ายเป็นp
. เราดำเนินการต่อในรูปแบบนี้จนกว่าเราจะกลับมาที่o
จุดเริ่มต้นและคืนจำนวนจุดยอดที่พบ (โปรดทราบว่าการนับจุดยอดคือ 1 ในขั้นต้นตั้งแต่จุดเริ่มต้นo
เป็นจุดสุดยอด)
ภาพด้านล่างแสดงจุดยอดที่ตรวจพบ โปรดทราบว่าการรับp
ตำแหน่งปัจจุบันของแต่ละจุดตรวจเนื่องจากตำแหน่งของจุดสุดยอดใหม่นั้นไม่เหมาะสมเนื่องจากจุดสุดยอดที่แท้จริงน่าจะอยู่ที่จุดใดจุดหนึ่งระหว่างจุดตรวจสุดท้ายq
และp
ตามแนวเส้นรอบวง อย่างที่คุณเห็นจุดยอดทั้งหมดที่นอกเหนือจากจุดแรก (โดยทั่วไปจุดยอดขวาล่าง) จะปิดเล็กน้อย การแก้ไขสิ่งนี้จะมีราคาสูงกว่าไบต์ แต่ดูเหมือนว่าจะทำงานได้ดีพอเหมือนเดิม ที่ถูกกล่าวว่ามันเป็นเรื่องยากเล็กน้อยที่จะไม่เหมาะกับกรณีทดสอบเพียงสี่
