Project Euler #44 in Ruby

Categories: Project Euler

My solution to this problem is definitely not the fastest. In fact, I’m certain it’s not. It takes about a few minutes to fully run. BUT more importantly it gives us the correct answer and it makes me feel a little better about myself for having done it. Here is the question text:

Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first ten pentagonal numbers are: 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, … It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 − 22 = 48, is not pentagonal.Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised; what is the value of D?

Solution:

Here’s my solution. Basically I wrote three functions: one which generates a list of pentagonal numbers up to a limit, one to check if the sum of any two numbers is pentagonal, and one to check if the absolute value of the difference between any two is pentagonal. Their powers unite to generate this:

def pent_numbers(limit)
	final = []
	1.upto(limit) do |num|
		final << ((num*((3*num)-1)) / 2)
	end
	final
end

def sum_pent?(a,b,pent_numbers)
	pent_numbers.include?(a+b) ? true : false
end

def difference_pent?(a,b,pent_numbers)
	pent_numbers.include?((a-b).abs) ? true : false
end

def sum_minus_pents
	all_pent = pent_numbers(3000)
	all_pent.each do |pent|	
		all_pent.each do |pent_b|
			if sum_pent?(pent,pent_b,all_pent) && difference_pent?(pent,pent_b,all_pent)
				puts "#{pent} and #{pent_b} fit the bill!"
				puts "Difference is #{(pent-pent_b).abs}"
			end
		end
	end
end

It’s so slow because it’s running through the entire list each time. I’m sure there are some simple ways to improve the speed of the code but for now, I’m happy to just have it done.

«
»