Acabei refazendo, porque achei a idéia interessante.
Tem a lista de cada UF, e a lista das UFs vizinhas de cada uma.
A rotina vai testando a passagem pelas vizinhas, até encontrar uma lista que chegue ao destino.
Código: Selecionar todos
PROCEDURE Main
SetMode(33,100)
CLS
AltD()
? "SP-RJ"
? hb_ValToExp( TrajetoPorUF( "SP", "RJ" ) )
? "SP-SE"
? hb_ValToExp( TrajetoPorUF( "SP", "SE" ) )
? "SP-RS"
? hb_ValToExp( TrajetoPorUF( "SP", "RS" ) )
? "RR-SP"
? hb_ValToExp( TrajetoPorUF( "RR", "SP" ) )
Inkey(0)
RETURN
FUNCTION TrajetoPorUF( cUFOrigem, cUFDestino )
LOCAL aList, aList2, aTrajeto, aNewList, cUF, xItem, xItem2
IF cUFOrigem == cUFDestino
? "Passando por: " + cUFOrigem
RETURN NIL
ENDIF
aList := { { cUFOrigem, { cUFOrigem } } }
DO WHILE .T.
IF Len( aList[1][2] ) > 20
? "Quase o Brasil inteiro na lista"
EXIT
ENDIF
FOR EACH xItem IN aList
IF xItem[1] == cUFDestino
RETURN xItem[2]
ENDIF
NEXT
cUF := aList[1][1]
aList2 := aList[1][2]
hb_ADel( aList, 1, .T. )
aTrajeto := GetVizinhos( cUF )
//? "vizinhos", nPass, hb_ValToExp( aTrajeto )
//Inkey(10)
FOR EACH xItem IN aTrajeto
aNewList := {}
FOR EACH xItem2 IN aList2
AAdd( aNewList, xItem2 )
NEXT
AAdd( aNewList, xItem )
//? "adicionado", nPass, hb_ValToExp( { xItem, aNewList } )
//Inkey(10)
AAdd( aList, { xItem, aNewList } )
NEXT
ENDDO
? "Não foi possível encontrar trajeto entre " + cUFOrigem + " e " + cUFDestino
RETURN NIL
FUNCTION GetVizinhos( cUF )
LOCAL aVizinhos := { ;
{ "AC", { "AM", "RO" } }, ;
{ "AL", { "PE", "SE", "BA" } }, ;
{ "AP", { "PA" } }, ;
{ "AM", { "RR", "PA", "MT", "RO", "AC" } }, ;
{ "BA", { "SE", "AL", "PE", "PI", "TO", "GO", "MG", "ES" } }, ;
{ "CE", { "PI", "PE", "PB", "RN" } }, ;
{ "DF", { "GO", "MG" } }, ;
{ "ES", { "BA", "MG", "RJ" } }, ;
{ "GO", { "DF", "MG", "BA", "TO", "MT", "MS" } }, ;
{ "MA", { "PI", "TO", "PA" } }, ;
{ "MT", { "PA", "TO", "GO", "MS", "RO", "AM" } }, ;
{ "MS", { "MT", "GO", "MG", "SP", "PR" } }, ;
{ "MG", { "SP", "RJ", "ES", "BA", "GO", "DF", "MS" } }, ;
{ "PA", { "AP", "MA", "TO", "MT", "AM" } }, ;
{ "PB", { "RN", "CE", "PE" } }, ;
{ "PR", { "SP", "MS", "SC" } }, ;
{ "PE", { "PB", "CE", "PI", "BA", "AL" } }, ;
{ "PI", { "MA", "TO", "BA", "PE", "CE" } }, ;
{ "RJ", { "ES", "MG", "SP" } }, ;
{ "RN", { "PB", "CE" } }, ;
{ "RS", { "SC" } }, ;
{ "RO", { "AC", "AM", "MT" } }, ;
{ "RR", { "AM", "PA" } }, ;
{ "SC", { "PR", "RS" } }, ;
{ "SP", { "RJ", "MG", "MS", "PR" } }, ;
{ "SE", { "BA", "AL" } }, ;
{ "TO", { "MA", "PI", "BA", "GO", "MT", "PA" } } ;
}
LOCAL nPos
nPos := hb_ASCAN( aVizinhos, {|e| e[1] == cUF } )
IF nPos > 0
RETURN aVizinhos[ nPos, 2 ]
ENDIF
RETURN {} // Sem vizinhos encontrados (não deve ocorrer para UFs válidas)
