from collections import namedtuple

Explorer = namedtuple('Explorer', 'row,col,direction')

movement = { '>': (0,1), '<': (0,-1), '^': (-1,0), 'V': (1,0) }

turns = {'>': ('V', '<', '^'), 'V': ('<', '^', '>'),
         '<': ('^', '>', 'V'), '^': ('>', 'V', '<')}

def turn_right(direction):
    return turns[direction][0]

def turn_around(direction):
    return turns[direction][1]

def turn_left(direction):
    return turns[direction][2]

def move(row, col, direction, spaces=1):
    r = row + movement[direction][0]*spaces
    c = col + movement[direction][1]*spaces
    return r, c

def navigate(maze):
    maze = maze.splitlines()
    # Find explorer
    for r, row in enumerate(maze):
        for c, cell in enumerate(row):
            if cell in '><^V':
                explorer = Explorer(r, c, cell)
                break
    states = {explorer}

    r, c = explorer.row, explorer.col
    d = explorer.direction
    while True:
        # Keep moving according to the rules until we reach
        # the exit or a repeated state
        for i in range(6):
            if maze[r][c] == 'E':
                return True
            next_r, next_c = move(r,c,d)
            if maze[next_r][next_c] == '#':
                # If a wall is in my way I turn to the right
                next_r, next_c = move(r,c,turn_right(d))
                if maze[next_r][next_c] == '#':
                    # if that not possible I turn to the left
                    next_r, next_c = move(r, c, turn_left(d))
                    if maze[next_r][next_c] == '#':
                        # if that is not possible I turn back from where I came
                        d = turn_around(d)
                        next_r, next_c = move(r, c, d)
                    else:
                        d = turn_left(d)
                else:
                    d = turn_right(d)
            r, c = next_r, next_c
        d = turn_right(turn_right(d))
        if Explorer(r, c, d) in states:
            # We've seen this before. The maze can't be solved.
            return False
        states.add(Explorer(r, c, d))


mazes = [
'''#######
#>   E#
#######''',

'''#####E#
#<    #
#######''',

'''##########
#>      E#
##########''',

'''#####E#
##### #
#>    #
##### #
#######''',

'''#####E#
##### #
##### #
##### #
##### #
#>    #
##### #
#######''']

challenges = ['''#########
#E ######
##      #
##### # #
#>    ###
##### ###
##### ###
##### ###
##### ###
##### ###
##### ###
#########''',

'''#########
#E ######
##      #
## ## # #
##### # #
#>    ###
##### ###
##### ###
##### ###
##### ###
##### ###
##### ###
#########''']

for maze in mazes:
    print(navigate(maze))
for maze in challenges:
    print(navigate(maze))