patternrubyMinor
Product of 2 numbers equals sum of numbers between them
Viewed 0 times
numbersproductbetweenequalssumthem
Problem
Problem:
Find all the pairs (a, b) whose product is equal to the sum of all numbers in the sequence [1..n] excluding both a and b.
I have made code for one program and need refactoring for code to get execution in less time. I am currently getting 13 sec for 500 number range.
Find all the pairs (a, b) whose product is equal to the sum of all numbers in the sequence [1..n] excluding both a and b.
I have made code for one program and need refactoring for code to get execution in less time. I am currently getting 13 sec for 500 number range.
def get_correct_array(n)
beginning_time = Time.now
puts " Begin with #{Time.now}"
mul = 0
arr = []
last_arr = []
(1..n).each do |x|
(x+1..n).each do |y|
mul = x * y
result = (1..n).reject {|n| n == x || n == y}.inject(&:+)
if result == mul
arr.concat([x,y])
@x = x
@y = y
end
end
end
last_arr #{(end_time - beginning_time)}"
p last_arr
endSolution
Some notes:
I'd write:
With n = 500` it takes ~0.1s in my machine. If this is not still fast enough, you can still filter out pair values on the range that are too small to possibly match the sum range.
- Use 2 spaces for indentation.
mul = 0No need to define variables in Ruby.
@x = x.@nameis a instance variable, but there is no class here. Use only local variables.
(1..n).reject {|n| n == x || n == y}.inject(&:+). That's very slow, you should pre-compute the sum before, and just subtract the two elements in every loop.
last_arr
- Make functions/methods return something.
- You can use the simple formula n * (n + 1) / 2
for the sum of (1..n).
- Your code is very, very imperative. For mathematical problems (if not for all), favor a functional style (immutable data-structures)
I'd write:
def get_pairs(n)
range_sum = (n * (n + 1)) / 2
pairs = (1..n).to_a.combination(2)
matching_pairs = pairs.select { |x, y| x * y == range_sum - x - y }
matching_pairs.flat_map { |x, y| [[x, y], [y, x]] }
end
p get_pairs(26) #=> [[15, 21], [21, 15]]With n = 500` it takes ~0.1s in my machine. If this is not still fast enough, you can still filter out pair values on the range that are too small to possibly match the sum range.
Code Snippets
def get_pairs(n)
range_sum = (n * (n + 1)) / 2
pairs = (1..n).to_a.combination(2)
matching_pairs = pairs.select { |x, y| x * y == range_sum - x - y }
matching_pairs.flat_map { |x, y| [[x, y], [y, x]] }
end
p get_pairs(26) #=> [[15, 21], [21, 15]]Context
StackExchange Code Review Q#124569, answer score: 2
Revisions (0)
No revisions yet.