Python 3, score = 1,57
D'abord, notre serpent parcourt l'image en créant des lignes verticales à égale distance les unes des autres.
Nous pouvons étendre ce serpent en prenant deux points l'un à côté de l'autre sur une ligne verticale et en créant une boucle dont les points d'extrémité sont eux.
| |
| => +----+
| +----+
| |
Nous organisons les points en paires et pour chaque paire, nous stockons la taille et la valeur de luminosité moyenne de la boucle qui donne la luminosité moyenne la plus élevée.
À chaque étape, nous choisissons la paire avec la valeur la plus élevée, étendez sa boucle pour obtenir une luminosité moyenne maximale sur l'extension et calculons la nouvelle taille de boucle et la valeur de luminosité optimales pour la paire.
Nous stockons les triplets (value, size, point_pair) dans une structure de tas triée par valeur afin que nous puissions supprimer le plus grand élément (dans O (1)) et ajouter le nouveau modifié (dans O (log n)) efficacement.
Nous nous arrêtons lorsque nous atteignons la limite de nombre de pixels et ce serpent sera le serpent final.
La distance entre les lignes verticales a très peu d'effet sur les résultats, donc un pixel constant de 40 pixels a été choisi.
Résultats
swirl 1.33084397946
chaos 1.76585674741
fractal 1.49085737611
bridge 1.42603926741
balls 1.92235115238
scream 1.48603818637
----------------------
average 1.57033111819
Remarque: l'image originale "The Scream" n'était pas disponible, j'ai donc utilisé une autre image "The Scream" avec une résolution similaire.
Gif montrant le processus d'extension du serpent sur l'image "tourbillon":
Le code prend un (ou plusieurs noms séparés par des espaces) de stdin et écrit les images de serpent résultantes dans des fichiers png et imprime les scores sur 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)
.