Jsevillamol
Jsevillamol

Reputation: 2543

Paths in python

Consider a rectangular grid.

I want a short and elegant way of generating a straight path from [x0,y0] to [x1,y1], where either x0=x1 or y0 = y1.

For example, on input [1,3], [3,3] the output [[1,3],[2,3],[3,3] should be generated. Likewise if the input is [3,3], [1,3].

I have tried [[i,j] for i in range(self.origin[0],self.end[0]+1) for j in range(self.origin[1], self.end[1]+1)], but it only works for the case where the input is ordered.

Upvotes: 0

Views: 51

Answers (2)

Adam Smith
Adam Smith

Reputation: 54163

Your question states that the solution from x -> y should be the same as the solution y -> x, i.e. we're only interested in defining the points on the path, not in any ordering of those points. If that's true, then simply find out which path has the smaller x (or y) and designate that as the origin.

origin = (3,3)
dest = (1,3)

origin, dest = sorted([origin, dest])

path = {(i,j) for i in range(origin[0], dest[0]+1) for j in range(origin[1], dest[1]+1)}
# note that this is now a set comprehension, since it doesn't make any sense
# to use a list of unique hashable items whose order is irrelevant

of course, this solves any obstructionless 2-D pathfinding. If you know that only one direction is changing, then only look in that direction.

origin, dest = sorted((origin, dest))
if origin[0] == dest[0]:  # y is changing
    path = {(origin[0], j) for j in range(origin[1], dest[1]+1)}
else:  # x is changing
    path = {(i, origin[1]) for i in range(origin[0], dest[0]+1)}

Upvotes: 3

Prune
Prune

Reputation: 77827

Add the step argument to your range, deriving the sign of the start & end difference:

x_dir = copysign(1, self.end[0] - self.origin[0])
... for i in range(self.origin[0], self.end[0]+1, x_dir) ...

Do likewise for the y direction.

Upvotes: 1

Related Questions