Intersection of circles – How can I reduce this golf code to 127 bytes?

Use Python 2's arg unpacking: 124 bytes

from math import*;circleIntersection=lambda(v,w),(x,y),r:r*r*(lambda h:h<1and acos(h)-h*(1-h*h)**.5)(hypot(v-x,w-y)/r/2)//.5

Try it online!

Python 2 has parameter unpacking, allowing the input point arguments to be taken directly as pairs (v,w) and (x,y), where the input lists like [0,0] and [0,10] will be unpacked into the respective variables. This feature was removed in Python 3 -- a pity, in my opinion, since the old syntax seems more readable. But, the site has a Python 2 option, and nothing in your solution relies on Python 3.


Use def: 125 bytes

You have a classic dilemma of wanting to assign to a variable without losing the brevity of a lambda function. Your method of using an inner lambda for assignment is one solution. The problem site not having Python 3.8 means the walrus operator is unfortunately off limits.

But, it's shorter here to just use def and suck up the bytes of writing out return. This is generically a 7-byte cost according to this reference. Within the def, we can just write the statement h= to do the assignment. We put everything on one line separated with ; to avoid needing to indent.

125 bytes

from math import*
def circleIntersection(a,b,r):h=hypot(b[0]-a[0],b[1]-a[1])/r/2;return(h<1and acos(h)-h*(1-h*h)**.5)*r*r//.5

Try it online! (vs original)

I've changed the multiplication order from return r*r*(...)//.5 to return(...)*r*r//.5 to cut the space after return.

There are likely other byte saves, including FryAmTheEggman's switch to numpy, but refactoring from lambda to def is already enough to get below 128 bytes.


Direct translation to NumPy: 127 bytes

from numpy import*
circleIntersection=lambda a,b,r:r*r*(lambda h:h<1and arccos(h)-h*(1-h*h)**.5)(hypot(*subtract(b,a))/r/2)//.5

Try it online!

Converting your code to numpy seems to save the required bytes. While using hypot is still ugly, being able to splat the result of subtract is still enough shorter that the loss of converting to arccos doesn't matter.

It is possible this can save more since it doesn't error on h<1 and will return nan in the case that the circles do not intersect. I don't know if that is permissible though since nan is not equal to zero.

I'm not convinced this is optimal, in particular I didn't look at improving the algorithm at all.