Project Euler #44 in Ruby
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.