#!/usr/bin/env python3 import math,random W,H=140,110 pos=[(x,y) for y in range(0,H+1,5) for x in range(0,W+1,5)] def cmask(x,y,r): z=0 for j in range(H): dy=j+.5-y;t=r*r-dy*dy if t>=0: d=math.sqrt(t);l=max(0,math.ceil(x-d-.5));u=min(W-1,math.floor(x+d-.5)) if u>=l:z|=((1<<(u-l+1))-1)<<(j*W+l) return z def smask(x,y): z=0;l=max(0,math.ceil(x-5.5));u=min(W-1,math.floor(x+4.5)) for j in range(H): if abs(j+.5-y)<=5 and u>=l:z|=((1<<(u-l+1))-1)<<(j*W+l) return z M=[[cmask(x,y,20) for x,y in pos],[cmask(x,y,5) for x,y in pos],[smask(x,y) for x,y in pos]] pc=lambda z:bin(z).count('1') def run(types,seed): random.seed(seed);s=[];u=0 for t in types: v=sorted((pc(u|m),i) for i,m in enumerate(M[t])) q=1 if seed==0 else min(15,len(v));_,i=random.choice(v[-q:]);s.append((t,i));u|=M[t][i] cur=pc(u) for sweep in range(2): order=list(range(len(s)));random.shuffle(order) for q in order: base=0 for k,(t,i) in enumerate(s): if k!=q:base|=M[t][i] t=s[q][0];v,i=max((pc(base|m),i) for i,m in enumerate(M[t])) if v>cur:s[q]=(t,i);cur=v return cur,s n2,n1,nr=8,0,42 types=[0]*n2+[2]*nr+[1]*n1 best=max(run(types,q) for q in range(2)) print('RESULT',best[0],best[0]/15400,20000*n2+1600*n1+2000*nr) print([(t,pos[i]) for t,i in best[1]])