CodeWords

Code, in words.

Project Euler Problem #12 Solution

leave a comment »

By the use of a theorem and a (relatively) efficient factorization algorithm, we can solve this problem fairly quickly. First, the theorem:

Theorem. If n = p_1^{\alpha_1} \cdots p_s^{\alpha_s}, then

\displaystyle d(n) = (\alpha_1 + 1)(\alpha_2 + 1) \cdots (\alpha_s + 1) = \prod_{i=1}^s (\alpha_i + 1).

This theorem tells us that if we can decompose n into its prime factors, we can efficiently calculate the number of divisors of n. It remains, therefore, for us to find a sufficiently efficient factorization algorithm. How about this:

def prime_factorization(n):
	divisor = 2
	while n > 1:
		factors = []
		while n % divisor == 0:
			factors.append(divisor)
			n /= divisor
		if factors:
			yield factors
		divisor += 1

This algorithm starts with a divisor of 2 and, if n is divisible by the divisor, it divides n by the divisor as long as n is still divisible by the divisor. When n no longer is, it increments the divisor and tries again until n is reduced to 1. Furthermore, each of the prime factors of n that equal each other are grouped into subsequences. That is, for n = 1701, we get [[3, 3, 3, 3, 3], [7]]. This makes it easier to use the theorem above.

We use a generator function to yield the triangle numbers, and a divisor-counting function that makes use of the theorem above, to get the desired number. All of the code, then, together, is:

def triangle_numbers():
	n = 1
	while True:
		yield n * (n + 1) / 2
		n += 1

def prime_factorization(n):
	candidate_factor = 2
	while n > 1:
		factors = []
		while n % candidate_factor == 0:
			factors.append(candidate_factor)
			n /= candidate_factor
		if factors:
			yield factors
		candidate_factor += 1

def count_divisors(n):
	count = 1
	for tuple in prime_factorization(n):
		count *= (len(tuple) + 1) 
	return count

for t in triangle_numbers():
	if count_divisors(t) > 500:
		print t
		break

Advertisement

Written by Jeff

13 February 2011 at 9:14 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.