I read a problem about bullseyes in Google Code Jam. (The contest is over now, so it's okay to talk about it)
Maria starts with t millilitres of black paint, which she will use to draw rings of thickness 1cm (one centimetre). A ring of thickness 1cm is the space between two concentric circles whose radii differ by 1cm.
Maria draws the first black ring around a white circle of radius r cm.
The area of a disk with radius 1cm is π cm2. One millilitre of paint is required to cover area π cm2. What is the maximum number of black rings that Maria can draw?
By my calculations on paper, the area of paint to draw a bullseye with n rings, inner radius r, as a multiple of pi is 2*n**2 + n*(2*r-1)
So given t*pi
millitres of paint the problem is to find the greatest n such that f(n,r) <= t
.
This morning I solved that with binary search https://github.com/hickford/codejam/blob/master/2013/1A/bullseye/bullseye.py
I chose binary search over the quadratic equation because I'm very wary of floating point imprecision — in this problem t and r are integers as big as 10**18). Arithmetic imprecision bit me in a previous Code Jam.
But I'm curious. Can you shore up the quadratic equation to give the correct answer for equations with large integer coefficients? Do maths libraries like Sympy or Numpy have anything to offer me?
Demonstration that quadratic equation gives wrong answer for large inputs. For example, with r=308436464205151562
and t=1850618785230909388
. The quadratic equation to solve is
2*n**2 + 616872928410303123*n -1850618785230909388 <= 0
ie. the coefficients are
a = 2
b = 616872928410303123
c = -1850618785230909388
Computing in Python
> int((-b + math.sqrt(b**2 - 4*a*c)) / (2*a))
0
This is the wrong answer! The right answer (found by binary search) is 3
>>> n = 3
>>> 2*n**2 + 616872928410303123*n -1850618785230909388 <= 0
True