:- 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.