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

Idiomatic ruby to calculate distance to points on a graph

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
graphpointsdistanceidiomaticcalculateruby

Problem

Can this code be made more like idiomatic ruby using methods such as map or inject?

@random_tour is a variable length array of points on a graph:
[[0, 0], [2, 1], [4, 3]]

I want to calculate the distance to reach each point using the manhattan distance (number of moves horizontally + number of moves vertically).

For example, starting at [0, 0] - the next point [2, 1] is 2 moves horizontally, 1 move vertically which is 3 moves. The next point is [4, 3] which is 4 moves away from the last. Total number of moves is 7.

def cost
  i = 0
  total_cost = 0
  while i < @random_tour.length - 1 do
    total_cost += (@random_tour[i + 1][0] - @random_tour[i][0]).abs + (@random_tour[i + 1][1] - @random_tour[i][1]).abs
    i += 1
  end
  total_cost
end

Solution

Enumerable.each_cons(n) will pass the array items in groups of n, using a sliding window. So [pt1, pt2], [pt2, pt3], [pt3, pt4], etc.

After that you can use inject to calculate the distance and sum the points.

def manhattan(pt1, pt2)
  (pt1[0]-pt2[0]).abs + (pt1[1]-pt2[1]).abs
end

def cost
  @random_tour
    .each_cons(2)
    .inject(0) { |sum, pts| sum + manhattan(pts[0], pts[1]) }
end

Code Snippets

def manhattan(pt1, pt2)
  (pt1[0]-pt2[0]).abs + (pt1[1]-pt2[1]).abs
end

def cost
  @random_tour
    .each_cons(2)
    .inject(0) { |sum, pts| sum + manhattan(pts[0], pts[1]) }
end

Context

StackExchange Code Review Q#125775, answer score: 4

Revisions (0)

No revisions yet.