Problem 100

completed April 24, 2012

Comments

Three things made this problem run in 0.25 seconds.

Avoidance of floating point numbers. Because the numbers I was working with were so precise – out to many decimal places – this made the use of floating point numbers problematic. When a number should have been 0.5, the program did not recognize it. In order to avoid this all together, I used a little algebra and made sure each side of the equation did not use division.

Multiplication by square root of two over two. As this problem reaches infinity, the subtraction of 1 from the numerator and denominator will all but disappear. Thus, the limit reaches (number of blue)^2 / (total)^2. But since this will equal 1/2, therefore, (number of blue)/(total) will equal the square root of two over two. For each total number of discs that I ran through, I multiplied this by the square root of two over two. This because an irrational number and was going to be too low to be the number of blue discs. The ceiling function then gave the number of blue discs. This allowed the program to run at O(N).

Use of a multiplier to jump to the next number. I noticed that the ratio between each succeeding correct value of the total discs increases. I therefore used the ration between the last two total discs to jump to a number that would be closer to the next correct answer.

Code

root2 = float(2.0**0.5)/float(2.0)
br = 2
prev = 1

while True:
	b = int(br*root2) + 1
	if 2*b*(b-1) == br*(br-1):
		print b, br
		if br > 10**12:
			break
		mult = br/float(prev)
		prev = br
		br = int(br*mult)
	else:
		br += 1