HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Product of 2 numbers equals sum of numbers between them

Submitted by: @import:stackexchange-codereview··
0
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.

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
end

Solution

Some notes:

  • Use 2 spaces for indentation.



  • mul = 0 No need to define variables in Ruby.



  • @x = x. @name is 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.