Python 3,得分= 1.57
首先,我们的蛇会移动图像,以创建彼此等距的垂直线。
我们可以通过在一条垂直线上相邻接两个点并创建一个端点为端点的循环来扩展此蛇。
| |
| => +----+
| +----+
| |
我们将这些点组织成对,并为每对存储循环的大小和平均亮度值,该值给出了最大的平均亮度。
在每一步中,我们选择对值最大的一对扩展其环路,以在扩展上获得最大的平均亮度,并为该对计算新的最佳环路尺寸和亮度值。
我们将(value,size,point_pair)三胞胎存储在按值排序的堆结构中,这样我们就可以删除最大的元素(在O(1)中)并有效地添加新修改的元素(在O(log n)中)。
当我们达到像素数限制时,我们就停止了,那条蛇将成为最终的蛇。
垂直线之间的距离对结果影响很小,因此选择了恒定的40个像素。
结果
swirl 1.33084397946
chaos 1.76585674741
fractal 1.49085737611
bridge 1.42603926741
balls 1.92235115238
scream 1.48603818637
----------------------
average 1.57033111819
注意:原始的“尖叫”图片不可用,因此我使用了另一张具有类似分辨率的“尖叫”图片。
Gif在“漩涡”图像上显示蛇的延伸过程:
该代码从stdin中获取一个(或多个空格)文件名,并将生成的蛇图像写入png文件,并将分数打印至stdout。
from PIL import Image
import numpy as np
import heapq as hq
def upd_sp(p,st):
vs,c=0,0
mv,mp=-1,0
for i in range(st,gap):
if p[1]+i<h:
vs+=v[p[0],p[1]+i]+v[p[0]+1,p[1]+i]
c+=2
if vs/c>mv:
mv=vs/c
mp=i
return (-mv,mp)
mrl=[]
bf=input().split()
for bfe in bf:
mr,mg=0,0
for gap in range(40,90,1500):
im=Image.open(bfe)
im_d=np.asarray(im).astype(int)
v=im_d[:,:,0]+im_d[:,:,1]+im_d[:,:,2]
w,h=v.shape
fp=[]
sp=[]
x,y=0,0
d=1
go=True
while go:
if 0<=x+2*d<w:
fp+=[(x,y)]
fp+=[(x+d,y)]
sp+=[(x-(d<0),y)]
x+=2*d
continue
if y+gap<h:
for k in range(gap):
fp+=[(x,y+k)]
y+=gap
d=-d
continue
go=False
sh=[]
px=im.load()
pl=[]
for p in fp:
pl+=[v[p[0],p[1]]]
px[p[1],p[0]]=(0,127,0)
for p in sp:
mv,mp=upd_sp(p,1)
if mv<=0:
hq.heappush(sh,(mv,1,mp+1,p))
empty=False
pleft=h*w//3
pleft-=len(fp)
while pleft>gap*2 and not empty:
if len(sh)>0:
es,eb,ee,p=hq.heappop(sh)
else:
empty=True
pleft-=(ee-eb)*2
mv,mp=upd_sp(p,ee)
if mv<=0:
hq.heappush(sh,(mv,ee,mp+1,p))
for o in range(eb,ee):
pl+=[v[p[0],p[1]+o]]
pl+=[v[p[0]+1,p[1]+o]]
px[p[1]+o,p[0]]=(0,127,0)
px[p[1]+o,p[0]+1]=(0,127,0)
pl+=[0]*pleft
sb=sum(pl)/len(pl)
ob=np.sum(v)/(h*w)
im.save(bfe[:-4]+'snaked.png')
if sb/ob>mr:
mr=sb/ob
mg=gap
print(bfe,mr)
mrl+=[mr]
print(sum(mrl)/len(mrl))
[![image description](SE URL for downsized image)](URL for original image)
。