Skip to main content
2 of 3
added 2773 characters in body
randomra
  • 20.9k
  • 4
  • 46
  • 111

Python 3, score = 1.57

First we travel the image creating vertical lines with equal distance from each other.

a

We can extend this snake by taking two points next to each other in a vertical line and creating a loop whose endpoints are them.

|      |
|  =>  +----+
|      +----+
|      |

We organize the points into pairs and for every pair we store the size and average brightness value of the loop which gives has the greatest average brightness.

At every step we choose the pair with highest value extend its loop to achieve maximum average brightness on the extension and calculate the new optimal loop size and brightness value for the pair.

We store the (value,size,point_pair) triplets in a heap structure sorted by value so we can remove the biggest element (in O(1)) and add the new modified one (in O(log n)) efficiently.

We stop when we reachg the pixel count limit and that snake will be the final snake.

The distance between the vertical lines has very little effect in the results so a constant 40 pixel was choosen.

Results

swirl    1.33084397946
chaos    1.76585674741
fractal  1.49085737611
bridge   1.42603926741
balls    1.92235115238
scream   1.48603818637
----------------------
average  1.57033111819

a a a a a a

Note: the original "The Scream" picture was not available so I used an other "The Scream" picture with similar resolution.

Gif showing the snake extending process on the "swirl" image:

a

The code takes one (or more space separated) filename(s) from stdin and writes the resulting snake images to png files and prints the scores to 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))
randomra
  • 20.9k
  • 4
  • 46
  • 111