Skip to main content
added 4 characters in body
Source Link
J_H
  • 35.2k
  • 3
  • 32
  • 129

What is a? What is b? Hard to say. Plus we're treated to lots of cryptic subscripts, instead of e.g. .x or .y coordinate. Yech! TheAnd the check() signature suffers the same syndrome.

        if ... and [a[0][0]-1, a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0]+1, a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0],   a[0][1]+1] not in a[3]:
            ...
        if ... and [a[0][0],   a[0][1]-1] not in a[3]:
            return True

What is a? What is b? Hard to say. Plus we're treated to lots of cryptic subscripts, instead of e.g. .x or .y coordinate. Yech! The check() signature suffers the same syndrome.

        if ... and [a[0][0]-1,a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0]+1,a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0],  a[0][1]+1] not in a[3]:
            ...
        if ... and [a[0][0],  a[0][1]-1] not in a[3]:
            return True

What is a? What is b? Hard to say. Plus we're treated to lots of cryptic subscripts, instead of e.g. .x or .y coordinate. Yech! And the check() signature suffers the same syndrome.

        if ... and [a[0][0]-1, a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0]+1, a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0],   a[0][1]+1] not in a[3]:
            ...
        if ... and [a[0][0],   a[0][1]-1] not in a[3]:
            return True
Source Link
J_H
  • 35.2k
  • 3
  • 32
  • 129

tuple, not list

    # In queue i added elements [current location, Direction,Turn Counts,visited dots in list]
    queue.append([[0,0],'R',0,[]])
    queue.append([[0,0],'D',0,[]])

Prefer to write the origin location as (0, 0) rather than [0, 0]. Why? In python we use a tuple to model a C struct, a fixed-length collection of "different" things. We use a list to model an arbitrarily long collection of "same" thing. We're storing two integers here. But are they the "same"? No, certainly not, we impose an interpretation on \$x\$ coordinates which is very different from how we interpret a \$y\$ coordinate.

Similarly, instead of
[[0, 0], 'R', 0, []], prefer this 4-tuple:
((0, 0), 'R', 0, []). Notice that the final visited is perfect: it is a growing list of "same" thing, of visited coordinate pairs.

Using cryptic indexes 0 .. 3 is inconvenient. Prefer to define a namedtuple having four named elements.

Sometimes an immutable tuple is not suitable, and we'll instead choose a mutable @dataclass.

\$(Δx, Δy)\$ representation

The {L, R, U, D} str representation does not come from the Problem Statement, and it is not convenient in the implementation. Prefer a 2-tuple of deltas.

  • L: (-1, 0)
  • R: (0, 1)
  • U: (0, -1)
  • D: (0, 1)

Now you can uniformly add a delta to a location without four special cases.

The OP code as written would have benefited from an enum that mapped those four values to delta tuples. Even a dict lookup mapping would have been preferrable.

helpers

The move() and check() helpers are entirely appropriate; thank you for adding them.

def move(a, b):

Yikes! That is just a terrible signature. And doesn't come with a """docstring""" to help the Gentle reader out of this mess. The comment turns out to be insufficient, plus it should be promoted to a docstring.

What is a? What is b? Hard to say. Plus we're treated to lots of cryptic subscripts, instead of e.g. .x or .y coordinate. Yech! The check() signature suffers the same syndrome.

quadratic time complexity

        if ... and [a[0][0]-1,a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0]+1,a[0][1]]   not in a[3]:
            ...
        if ... and [a[0][0],  a[0][1]+1] not in a[3]:
            ...
        if ... and [a[0][0],  a[0][1]-1] not in a[3]:
            return True

Wow, that's a lot of linear scans of an increasingly long list. You do this often enough that it would be worth caching a set version of the same datastructure, to reduce the in complexity from \$O(n)\$ linear to \$O(1)\$ constant.

quadratic space complexity

        Up    = copy.deepcopy(p)
        Down  = copy.deepcopy(p)
        Right = copy.deepcopy(p)
        Left  = copy.deepcopy(p)

Wow, that's a lot of duplicate visited coordinates, by the time we get near the exit square.

Prefer to represent "current state" with this mapping:
(entry_direction, location) --> cost.
That is, we entered this location square in one of four ways, and cumulative price of constructing prior squares plus this square is cost. Now it suffices to create four (\$O(1)\$ constant space!) copies of this square, to enqueue four distinct deltas to explore.

You might find it convenient to have a defaultdict report such cost figures. For an as yet unexplored location, report some very large \$\infty\$ cost, perhaps math.float('inf').

We can read out a solution from any location, including the end location, by having DFS scan four adjacent cost values and carry on from there. The entry direction is easily turned into a reverse delta pointing at the next square, typically closer to the origin.

pruning

My code consumes lots of running time

Yeah, that's what comes of exhaustively exploring the space.

An A* consistent admissible heuristic here would be Manhattan distance. That is, pretend there's zero barriers between here and the goal. We'll need to make either zero, or typically one turn. Add up the turn cost, the \$x\$, and the \$y\$ distances to get the best possible "cost to goal", and use that to prioritize which paths to explore first.

Or, since this problem is simple enough, use Dijkstra.