path(X) :- path(X, []).
path([], _).
path([_], _).
path([A, B | T], VISTED) :-
passage(A, B),
not(member(B, [A | VISTED])),
path([B | T], [A | VISTED]).
first(H, [H | _]).
last(L, [L]).
last(L, [_ | T]) :- last(L, T).
tail(T, [_ | T]).
safe([]).
safe([_]).
safe([H | T]) :- not(grue(H)), safe(T).
safe_path(X) :-
path(X),
safe(X).
% Possibility one. Safe path from start to finish.
navigate(X) :-
safe_path(X),
first(F, X), start(F),
last(L, X), end(L).
% Possibility two. Safe path from start to sword. Path from sword to finish.
navigate(X) :-
append(START_TO_SWORD, TO_FINISH, X),
tail(TO_FINISH, SWORD_TO_FINISH),
sword(SWORD_POS),
end(FINISH_POS),
start(START_POS),
safe_path(START_TO_SWORD),
first(START_POS, START_TO_SWORD),
last(SWORD_POS, START_TO_SWORD),
path(SWORD_TO_FINISH),
first(SWORD_POS, SWORD_TO_FINISH),
last(FINISH_POS, SWORD_TO_FINISH).