Python 3, punteggio = 1,57
Innanzitutto il nostro serpente viaggia nell'immagine creando linee verticali con uguale distanza l'una dall'altra.
Possiamo estendere questo serpente prendendo due punti uno accanto all'altro in una linea verticale e creando un anello i cui punti finali sono loro.
| |
| => +----+
| +----+
| |
Organizziamo i punti in coppie e per ogni coppia memorizziamo le dimensioni e il valore di luminosità media del loop che dà la massima luminosità media.
Ad ogni passo scegliamo la coppia con il valore più alto estendere il suo loop per ottenere la massima luminosità media sull'estensione e calcolare la nuova dimensione del loop e il valore di luminosità ottimali per la coppia.
Archiviamo le terzine (value, size, point_pair) in una struttura heap ordinate per valore in modo da poter rimuovere l'elemento più grande (in O (1)) e aggiungere il nuovo modificato (in O (log n)) in modo efficiente.
Ci fermiamo quando raggiungiamo il limite di conteggio dei pixel e quel serpente sarà l'ultimo serpente.
La distanza tra le linee verticali ha un effetto molto limitato nei risultati, quindi è stato scelto un costante 40 pixel.
risultati
swirl 1.33084397946
chaos 1.76585674741
fractal 1.49085737611
bridge 1.42603926741
balls 1.92235115238
scream 1.48603818637
----------------------
average 1.57033111819
Nota: l'immagine originale "The Scream" non era disponibile, quindi ho usato un'altra immagine "The Scream" con una risoluzione simile.
Gif che mostra il processo di estensione del serpente sull'immagine "turbolenza":
Il codice prende uno (o più nomi di file separati dallo spazio) da stdin e scrive le immagini di serpenti risultanti in file png e stampa i punteggi su 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)
.