Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Black Holes by jcg
import math
def distance(c1,c2):
return math.hypot(c1[0] - c2[0], c1[1] - c2[1])
def absorption(c1, c2):
#return None if no absorption
# return new black hole if absorption
if c1[2] > c2[2]:
c1, c2 = c2, c1
r1, r2 = [c[2] for c in (c1, c2)]
area1, area2 = [math.pi * r ** 2 for r in (r1, r2)]
# c1, r1, area1 : little circle
# c2, r2, area2 : big circle
if area2 < 1.2 * area1: # too similar in size for absorption
return None
# compute intersection
d = distance(c1, c2)
if d >= r1 + r2: # circles too far for absorption
return None
elif d <= r2 - r1: # c1 all in c2
area_inter = area1
else: # http://mathworld.wolfram.com/Circle-CircleIntersection.html
area_inter = \
r1 ** 2 * math.acos((d ** 2 + r1 ** 2 - r2 ** 2) / (2 * d * r1)) + \
r2 ** 2 * math.acos((d ** 2 + r2 ** 2 - r1 ** 2) / (2 * d * r2)) - \
1 / 2 * math.sqrt(
(-d + r1 + r2) * (d - r1 + r2) * (d + r1 - r2) * (d + r1 + r2))
if area_inter >= 0.55 * area1: # intersection is sufficient for absorption
return type(c1)((c2[0], c2[1], math.sqrt((area1 + area2) / math.pi)))
else: # intersection too small for absorption
return None
def checkio(liste):
while True:
for x,y in sorted( # sort couples by increasing distances
list((x,y) for x in liste for y in liste if x != y),
key=lambda c: distance(*c)):
new = absorption(x, y) #compute absorption betweeen x, y
if new:
x, y = (x, y) if x[2] > y[2] else (y, x)
# x is the big, y is the little
liste[liste.index(x)] = new # the big becomes the new
liste.remove(y) # the little is absorpted
break # we have to loop again
else: # if for loop ended without break, work is finished
break
return [type(liste[0])((x, y, round(r, 2))) for x, y, r in liste]
Jan. 26, 2016
Comments: