Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Feel free to add more classes/helper functions if you like, code quality counts!
- import queue
- class RobotRouter:
- # This class will be initialized with the map features from the problem input.
- # barriers and laserCoordinates are arrays of Coordinate objects.
- # laserDirections is an array of strings representing the direction of
- # the corresponding laser in laserCoordinates.
- def __init__(self, barriers, laserCoordinates, laserDirections):
- self.barriers = set(barriers)
- self.lasers = instantiateLasers(barriers, laserCoordinates, laserDirections)
- # This method will be called to get your optimal route.
- # origin and destination are Coordinate objects (with x and y properties)
- # It should return a list of Coordinate objects,
- # starting with the origin and ending with the destination.
- # If you could not find a valid route, return an empty list.
- def route(self, origin, destination):
- nodes = queue.Queue()
- visited = {}
- prev = {}
- prev[origin] = origin
- nodes.put(origin)
- while not nodes.empty():
- lastnode = nodes.get()
- visited[lastnode] = True
- if lastnode == destination:
- # generating the path to return
- pathnode = lastnode
- path = []
- while prev[pathnode] != pathnode:
- path.append(pathnode)
- pathnode = prev[pathnode]
- path.append(pathnode)
- return path[::-1]
- up = Coordinate(lastnode.x, lastnode.y + 1)
- down = Coordinate(lastnode.x, lastnode.y - 1)
- right = Coordinate(lastnode.x + 1, lastnode.y)
- left = Coordinate(lastnode.x - 1, lastnode.y)
- if self.isAccessible(up) and up not in visited:
- nodes.put(up)
- prev[up] = lastnode
- if self.isAccessible(down) and down not in visited:
- nodes.put(down)
- prev[down] = lastnode
- if self.isAccessible(right) and right not in visited:
- nodes.put(right)
- prev[right] = lastnode
- if self.isAccessible(left) and left not in visited:
- nodes.put(left)
- prev[left] = lastnode
- return []
- def isAccessible(self, coordinate):
- if coordinate in self.barriers:
- return False
- for laser in self.lasers:
- if laser.hits(coordinate):
- return False
- return True
- def instantiateLasers(barriers, laserCoordinates, laserDirections):
- lasers = []
- for i in range(len(laserCoordinates)):
- origin = laserCoordinates[i]
- direction = laserDirections[i]
- laser = Laser(origin, direction)
- lasers.append(laser)
- for barrier in barriers:
- if direction == "N" and barrier.y > origin.y:
- if laser.limit == None:
- laser.limit = barrier
- else:
- laser.limit = Coordinate(origin.x, min(laser.limit.y, barrier.y))
- if direction == "S" and barrier.y < origin.y:
- if laser.limit == None:
- laser.limit = barrier
- else:
- laser.limit = Coordinate(origin.x, max(laser.limit.y, barrier.y))
- if direction == "E" and barrier.x > origin.x:
- if laser.limit == None:
- laser.limit = barrier
- else:
- laser.limit = Coordinate(min(laser.limit.x, barrier.x), barrier.y)
- if direction == "W" and barrier.x < origin.x:
- if laser.limit == None:
- laser.limit = barrier
- else:
- laser.limit = Coordinate(max(laser.limit.x, barrier.x), barrier.y)
- return lasers
- class Laser:
- def __init__(self, origin, direction, limit = None):
- self.origin = origin
- self.direction = direction
- self.limit = limit
- def hits(self, coord):
- if self.direction == "N":
- return coord.x == self.origin.x and coord.y >= self.origin.y and self.limit != None and coord.y < self.limit.y
- elif self.direction == "S":
- return coord.x == self.origin.x and coord.y <= self.origin.y and self.limit != None and coord.y > self.limit.y
- elif self.direction == "E":
- return coord.y == self.origin.y and coord.x >= self.origin.x and self.limit != None and coord.x < self.limit.x
- else:
- return coord.y == self.origin.y and coord.x <= self.origin.x and self.limit != None and coord.x > self.limit.x
- class Coordinate:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- def __eq__(self, other):
- return isinstance(other, self.__class__) and self.x == other.x and self.y == other.y
- def __hash__(self):
- return hash((self.x, self.y))
- def __str__(self):
- return '%d,%d' % (self.x, self.y)
- import sys
- def readCoordinate(rawCoordinate):
- parts = rawCoordinate.split(',')
- return Coordinate(int(parts[0]), int(parts[1]))
- def writeMapAndRoute(origin, destination, barriers, laserCoordinates, laserDirections, route):
- bottomLeft = origin
- topRight = origin
- for coordinate in (destination, *barriers, *laserCoordinates, *route):
- bottomLeft = Coordinate(min(bottomLeft.x, coordinate.x), min(bottomLeft.y, coordinate.y))
- topRight = Coordinate(max(topRight.x, coordinate.x), max(topRight.y, coordinate.y))
- barrierSet = set(barriers)
- lasers = { laserCoordinates[i]: laserDirections[i] for i in range(len(laserCoordinates)) }
- routeSet = set(route)
- for y in range(topRight.y, bottomLeft.y - 1, -1):
- for x in range(bottomLeft.x, topRight.x + 1):
- coordinate = Coordinate(x, y)
- if coordinate == origin:
- sys.stdout.write('o')
- elif coordinate == destination:
- sys.stdout.write('d')
- elif coordinate in barrierSet:
- sys.stdout.write('X')
- elif coordinate in lasers:
- direction = lasers[coordinate]
- if direction == 'N':
- sys.stdout.write('^')
- elif direction == 'E':
- sys.stdout.write('>')
- elif direction == 'W':
- sys.stdout.write('<')
- elif direction == 'S':
- sys.stdout.write('v')
- else:
- sys.stdout.write('?')
- elif coordinate in routeSet:
- sys.stdout.write('.')
- else:
- sys.stdout.write(' ')
- sys.stdout.write('\n')
- sys.stdout.write('\n')
- if route:
- sys.stdout.write('Route:\n')
- for coordinate in route:
- sys.stdout.write(str(coordinate))
- sys.stdout.write('\n')
- else:
- sys.stdout.write('No Route')
- def main():
- origin = readCoordinate(sys.stdin.readline().strip())
- destination = readCoordinate(sys.stdin.readline().strip())
- barriers = []
- laserCoordinates = []
- laserDirections = []
- barrierLine = sys.stdin.readline().strip()
- if barrierLine:
- barriers = [readCoordinate(barrier) for barrier in barrierLine.split(' ')]
- laserLine = sys.stdin.readline().strip()
- if laserLine:
- rawLasers = laserLine.split(' ')
- laserCoordinates = [readCoordinate(laser) for laser in rawLasers]
- laserDirections = [laser.rsplit(',', 1)[1] for laser in rawLasers]
- route = RobotRouter(barriers, laserCoordinates, laserDirections).route(origin, destination)
- writeMapAndRoute(origin, destination, barriers, laserCoordinates, laserDirections, route)
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement