Python 3, оцінка = 1,57
Спочатку наша змія подорожує зображення, створюючи вертикальні лінії з однаковою відстані один від одного.
Ми можемо розширити цю змію, взявши дві точки поруч один з одним по вертикалі і створивши петлю, кінцевими точками якої є вони.
| |
| => +----+
| +----+
| |
Ми впорядковуємо точки по парах, і для кожної пари ми зберігаємо розмір і середнє значення яскравості петлі, яке дає має найбільшу середню яскравість.
На кожному кроці ми вибираємо пару з найвищим значенням розширити її цикл для досягнення максимальної середньої яскравості на розширенні та обчислимо новий оптимальний розмір циклу та значення яскравості для пари.
Ми зберігаємо триплети (значення, розмір, 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)
.