import itertools import bisect cubs = [i**3 for i in xrange(1000000)] # needed for cubes_bisect def invpow(x, n): """ x , n > 0 integers return y, such that y ** n <= x and (y+1) ** n > x """ return int((x + 0.5) ** (1.0/3)) def cubes_bisect(n): """ using bisection to find x,y pairs - a little slower than cubes """ y = invpow(n, 3) x = 1 while x <= y: y3 = cubs[y] x = bisect.bisect_left(cubs, n - y3, x, y + 1) if cubs[x] + y3 == n: yield x, y x += 1 y -= 1 def cubes(n): """generator for all sums of 3rd powers to get n start with pair x, y, where y is the highest number, such that y**3<=n If n is odd, (x,y) can only be an odd-even pair. If n is even, (x,y) can only be odd-odd or even-even. While x^3+y^3 is smaller than n, x can advance with 2 steps i.s.o one step, as a one step increase cannot be a solution. If y is decreased x must increase to make sure that the sum can be a solution (is odd or even, like n). This version is about a factor 2 faster than cubes0 """ y = invpow(n, 3) y3 = y ** 3 x = 0 + (n - y) & 1 # make x odd if n - y^3 is odd while x <= y: test = x ** 3 + y3 if test < n: x += 2 else: if test == n: yield x, y x += 1 y -= 1 y3 = y ** 3 def check_cubes(n, ncubes): """check if number of cubes is ncubes for number n""" cub = list(itertools.islice(cubes(n), ncubes+1)) return cub if len(cub) == ncubes else False def list_numbers(maxnumber, ncubes): """ list all numbers with ncubes ways of writing it as the sum of 2 cubes """ for i in xrange(2, maxnumber): res = check_cubes(i, ncubes) if res: print i, res import time t0 = time.clock() list_numbers(100000, 2) print time.clock() - t0 """ 1729 [(1, 12), (9, 10)] 4104 [(2, 16), (9, 15)] 13832 [(2, 24), (18, 20)] 20683 [(10, 27), (19, 24)] 32832 [(4, 32), (18, 30)] 39312 [(2, 34), (15, 33)] 40033 [(9, 34), (16, 33)] 46683 [(3, 36), (27, 30)] 64232 [(17, 39), (26, 36)] 65728 [(12, 40), (31, 33)] """ import sys from time import clock t0 = clock() def taxicab(ncubes): """return lowest number with ncubes cubes""" n = 0 while 1: n += 1 if not n % 1000000: print n, clock() - t0 sys.stdout.flush() res = check_cubes(n, ncubes) if res: return n, res #print taxicab(3) # this takes 5268 sec -> 87539319 #print clock() - t0 def test_invpow(): """test for function invpow""" i = 2 while i < 100000000: a = invpow(i, 3) assert a ** 3 <= i assert (a+1)**3 > i i += 1234 def test_cubes(): """test if functions cubes and cubes0 give same solution""" i = 2 while i < 1000000: for e1,e2 in itertools.izip(cubes(i), cubes0(i)): assert e1 == e2 i += 1 def cubes0(n): """generator for all sums of 3rd powers to get n cubes is a faster version """ x = 0 y = invpow(n, 3) while x <= y: x3 = x ** 3 y3 = y ** 3 if x3 + y3 > n: y -= 1 elif x3 + y3 < n: x += 1 else: yield x, y x += 1 y -= 1