Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robot return to origin

Question:

There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its moves, judge if this robot ends up at (0, 0) after it completes its moves.

The move sequence is represented by a string, and the character moves[i] represents its ith move. Valid moves are R (right), L (left), U (up), and D (down). If the robot returns to the origin after it finishes all of its moves, return true. Otherwise, return false.

Note: The way that the robot is "facing" is irrelevant. "R" will always make the robot move to the right once, "L" will always make it move left, etc. Also, assume that the magnitude of the robot's movement is the same for each move.

Input: moves = "UD"
Output: true
Explanation: The robot moves up once, and then down once. 
All moves have the same magnitude, so it ended up at the origin where it started. 
Therefore, we return true.

I have the following solution, which seems to be wrong for sequences = "UD", which should return True. Could someone help me understand what I am doing wrong here and how I could fix it?

class Solution:

    class Mover:
        def __init__(self, x, y):
            self.x, self.y = x, y
        def new_pos(self, x, y):
            return x + self.x, y + self.y

    WALKS = dict(U=Mover(0, -1), D=Mover(0, 1),
                 L=Mover(-1, 0), R=Mover(1, 0))

    def judge_circle(self, moves):
        x = y = 0
        for id in moves:
            x, y = self.WALKS[id].new_pos(x, y)
        return x == y == 0

    def move_sequences(self,sequences):
        for moves in sequences:
            return (solution.judge_circle(moves))

if __name__ == "__main__":
    solution = Solution()
    sequences = "UD"
    print(solution.move_sequences(sequences))
like image 465
nerdyGuy Avatar asked Apr 19 '21 03:04

nerdyGuy


3 Answers

This solution seems overthinking it by quite a bit. You can just make a counter of each of the 4 directions and figure out if you have the same number of Us relative to Ds and Ls relative to Rs. return s.count("U") == s.count("D") and s.count("L") == s.count("R") gives you a linear solution that can be optimized into a single pass with something like

from collections import Counter
d = Counter(moves)
return d["D"] == d["U"] and d["R"] == d["L"]

As for your code,

        for moves in sequences:
            return (solution.judge_circle(moves))

looks funny to me. Returning on the first iteration means the loop is pointless. moves here is misleadingly named -- it's only a single character "U". judge_circle already does a loop, so if you really want to brute-force it, you'll only want one loop over the sequence rather than two.

like image 60
ggorlen Avatar answered Oct 21 '22 21:10

ggorlen


Your task is simple:

def judge_circle(moves):
    if moves.lower().count('U') == moves.lower().count('D') and moves.lower().count('L') == moves.lower().count('R'):
        return True
    else:
        return False
print(judge_circle('UD'))

You only have to check whether the number of 'ups' equals the numbers of 'downs', and 'lefts' equal 'rights'.

like image 42
Sid Avatar answered Oct 21 '22 22:10

Sid


Ok, a part from refactor advices, you can fix your script in a easy way.

def move_sequences(self,sequences):
    for moves in sequences:
        return (solution.judge_circle(moves))

fails because you pass a string in sequences and the for loop cycles over the letters, passing every single letter to judge_circle. Remove the for loop and pass sequences to judge_circle!

like image 1
Marco Avatar answered Oct 21 '22 21:10

Marco