52 lines
1.5 KiB
Prolog
52 lines
1.5 KiB
Prolog
:- use_module(library(pio)).
|
|
:- use_module(library(dcg/basics)).
|
|
:- initialization(main, main).
|
|
|
|
main([FileName|_]) :-
|
|
input(FileName, Map),
|
|
nth1(1, Map, Row1), nth1(StartY, Row1, '.'),
|
|
findall(N, route(Map, visited{}, 1-StartY, N), Ns),
|
|
max_list(Ns, Answer),
|
|
format('~w <- ~w', [Answer, Ns]), nl.
|
|
|
|
route(Map, _, X-_, 0) :- length(Map, Height), X =:= Height.
|
|
route(Map, Visiteds, X-Y, N) :-
|
|
Key is X*1000 + Y, NextVisiteds = Visiteds.put(Key, true),
|
|
neighbor(Map, X-Y, X1-Y1, Dist),
|
|
NeighborKey is X1*1000 + Y1, \+ _= Visiteds.get(NeighborKey),
|
|
route(Map, NextVisiteds, X1-Y1, N1),
|
|
N is N1 + Dist.
|
|
|
|
neighbor(Map, X-Y, NextX-NextY, Dist) :-
|
|
( X1 is X + 1, Y1 = Y;
|
|
X1 is X - 1, Y1 = Y;
|
|
X1 = X, Y1 is Y + 1;
|
|
X1 = X, Y1 is Y - 1
|
|
),
|
|
nth1(X1, Map, Row1), nth1(Y1, Row1, Cell1),
|
|
( Cell1 = '.' -> NextX = X1, NextY = Y1, Dist = 1
|
|
; Cell1 = '>' -> NextX = X1, NextY is Y1 + 1, Dist = 2
|
|
; Cell1 = 'v' -> NextX is X1 + 1, NextY = Y1, Dist = 2
|
|
),
|
|
( NextX =\= X; NextY =\= Y ).
|
|
|
|
% input parsing stuff below. Brick indexing is for debugging.
|
|
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
|
|
|
|
lines([]) --> eos, !.
|
|
lines([Line|Lines]) --> line(Line), lines(Lines).
|
|
|
|
line([]) --> ("\n"; eos), !.
|
|
line([C|Chars]) --> [Ascii], line(Chars), {atom_codes(C, [Ascii])}.
|
|
|
|
% debug
|
|
print(Map) :-
|
|
findall(
|
|
X,
|
|
( nth1(X, Map, Line),
|
|
format('~3d', [X]), write(" "),
|
|
atomic_list_concat(Line, Str), write(Str), nl
|
|
),
|
|
_),
|
|
nl.
|