E= enumerate
def U( D, x, X) :D[ x] = D.get ( x, [ ] ) +[ X] ; D[ X] = D.get ( X, [ ] ) +[ x]
def f( b) :
m, W= [ [ 0 , 1 , '-^' ] , [ 1 , 0 , '|>' ] , [ 0 , -1 , '-^' ] , [ -1 , 0 , '|>' ] ] , { '^' :'-' , '>' :'|' } ; x, y= [ [ x, y] for x, r in E( b) for y, t in E( r) if '$' == t] [ 0 ] ; V= lambda X, Y:len ( b) > X> -1 < Y< len ( b[ 0 ] ) and b[ X] [ Y] != ' ' ; q, D= [ ( x, y, 0 , 1 -V( x, y+1 ) ) ] , { }
while q:
x, y, p, l= q.pop ( 0 )
if '#' == b[ x] [ y] :return p
if b[ x] [ y] in '>^' :
for j, k, I in [ ( X, Y, i) for i, ( X, Y, u) in E( m) if b[ x] [ y] in u] +[ ( m[ l] [ 0 ] , m[ l] [ 1 ] , l) ] :
if ( ( x+j, y+k) in D.get ( ( x, y) , [ ] ) ) < ( ( z:= b[ x+j] [ y+k] ) in '>#^+' or z== W[ b[ x] [ y] ] ) :U( D, ( x, y) , ( x+j, y+k) ) ; q+= ( x+j, y+k, p+1 , I) ,; break
elif '+' == b[ x] [ y] :
T, O= [ 0 , 1 , 2 , 3 ] , [ ]
for i in T[ l:] +T[ :l] :
if V( X:= x+m[ i] [ 0 ] , Y:= y+m[ i] [ 1 ] ) > ( ( X, Y) in D.get ( ( x, y) , [ ] ) ) :
if '#' == b[ X] [ Y] :return-~ p
O+= ( ( X, Y) , i) ,
if O:U( D, ( x, y) , O[ 0 ] [ 0 ] ) ; q+= ( *O[ 0 ] [ 0 ] , p+1 , O[ 0 ] [ 1 ] ) ,
elif V( X:= x+m[ l] [ 0 ] , Y:= y+m[ l] [ 1 ] ) and b[ X] [ Y] in ( m[ l] [ 2 ] +'#+' ) :U( D, ( x, y) , ( X, Y) ) ; q+= ( X, Y, p+1 , l) ,
def to_board( d) :
return [ [ *i] for i in filter ( None , d.split ( '\n ' ) ) ]
s1 = """
$
|
+-|
#+-+
"""
s2= """
#-+-+
| |
$-^-+
+-+
"""
s3= """$#"""
s4= """
#^^^^+
>
$----^-+
> +
+-+
"""
s5= """
$------+
|-----+|
--#--+|
+--+---+
+------+
"""
s6 = """$ #"""
s7 = """$|#"""
s8= """
$
-
#"""
s9= """
$|#
|--|
++++
"""
print ( f( to_board( s1) ) )
print ( f( to_board( s2) ) )
print ( f( to_board( s3) ) )
print ( f( to_board( s4) ) )
print ( f( to_board( s5) ) )
print ( f( to_board( s6) ) )
print ( f( to_board( s7) ) )
print ( f( to_board( s8) ) )
print ( f( to_board( s9) ) )
RT1lbnVtZXJhdGUKZGVmIFUoRCx4LFgpOkRbeF09RC5nZXQoeCxbXSkrW1hdO0RbWF09RC5nZXQoWCxbXSkrW3hdCmRlZiBmKGIpOgogbSxXPVtbMCwxLCctXiddLFsxLDAsJ3w+J10sWzAsLTEsJy1eJ10sWy0xLDAsJ3w+J11dLHsnXic6Jy0nLCc+JzonfCd9O3gseT1bW3gseV1mb3IgeCxyIGluIEUoYilmb3IgeSx0IGluIEUocilpZickJz09dF1bMF07Vj1sYW1iZGEgWCxZOmxlbihiKT5YPi0xPFk8bGVuKGJbMF0pYW5kIGJbWF1bWV0hPScgJztxLEQ9Wyh4LHksMCwxLVYoeCx5KzEpKV0se30KIHdoaWxlIHE6CiAgeCx5LHAsbD1xLnBvcCgwKQogIGlmJyMnPT1iW3hdW3ldOnJldHVybiBwCiAgaWYgYlt4XVt5XWluJz5eJzoKICAgZm9yIGosayxJIGluWyhYLFksaSlmb3IgaSwoWCxZLHUpaW4gRShtKWlmIGJbeF1beV1pbiB1XStbKG1bbF1bMF0sbVtsXVsxXSxsKV06CiAgICBpZigoeCtqLHkraylpbiBELmdldCgoeCx5KSxbXSkpPCgoejo9Ylt4K2pdW3kra10paW4nPiNeKydvciB6PT1XW2JbeF1beV1dKTpVKEQsKHgseSksKHgraix5K2spKTtxKz0oeCtqLHkrayxwKzEsSSksO2JyZWFrCiAgZWxpZicrJz09Ylt4XVt5XToKICAgVCxPPVswLDEsMiwzXSxbXQogICBmb3IgaSBpbiBUW2w6XStUWzpsXToKICAgIGlmIFYoWDo9eCttW2ldWzBdLFk6PXkrbVtpXVsxXSk+KChYLFkpaW4gRC5nZXQoKHgseSksW10pKToKICAgICBpZicjJz09YltYXVtZXTpyZXR1cm4tfnAKICAgICBPKz0oKFgsWSksaSksCiAgIGlmIE86VShELCh4LHkpLE9bMF1bMF0pO3ErPSgqT1swXVswXSxwKzEsT1swXVsxXSksCiAgZWxpZiBWKFg6PXgrbVtsXVswXSxZOj15K21bbF1bMV0pYW5kIGJbWF1bWV1pbihtW2xdWzJdKycjKycpOlUoRCwoeCx5KSwoWCxZKSk7cSs9KFgsWSxwKzEsbCksCiAgCmRlZiB0b19ib2FyZChkKToKCXJldHVybiBbWyppXWZvciBpIGluIGZpbHRlcihOb25lLCBkLnNwbGl0KCdcbicpKV0KCnMxID0gIiIiCiAgICQKICAgfCAKICstfAojKy0rCiIiIgpzMj0iIiIKIy0rLSsKICB8IHwKJC1eLSsKICArLSsKIiIiCnMzPSIiIiQjIiIiCgpzND0iIiIKI15eXl4rICAKICAgICA+ICAgCiQtLS0tXi0rCiAgICAgPiArCiAgICAgKy0rCiIiIgpzNT0iIiIKJC0tLS0tLSsKfC0tLS0tK3wKIC0tIy0tK3wKKy0tKy0tLSsKKy0tLS0tLSsKIiIiCnM2ID0gIiIiJCAjIiIiCnM3ID0gIiIiJHwjIiIiCnM4PSIiIgokCi0KIyIiIgpzOT0iIiIKJHwjCnwtLXwKKysrKwoiIiIKcHJpbnQoZih0b19ib2FyZChzMSkpKQpwcmludChmKHRvX2JvYXJkKHMyKSkpCnByaW50KGYodG9fYm9hcmQoczMpKSkKcHJpbnQoZih0b19ib2FyZChzNCkpKQpwcmludChmKHRvX2JvYXJkKHM1KSkpCnByaW50KGYodG9fYm9hcmQoczYpKSkKcHJpbnQoZih0b19ib2FyZChzNykpKQpwcmludChmKHRvX2JvYXJkKHM4KSkpCnByaW50KGYodG9fYm9hcmQoczkpKSk=