@anon95304481 I can’t understand what it is in @meditans code which makes it run so much faster than mine. It runs for part 1 in 0.5 seconds allegedly, mine takes 30 seconds:
:- use_module(library(dcg/basics)).
ns(N,V) :- number_string(N,V).
t(_,_,[]) --> [].
t(X0,_,Xs) --> "\n",{X is X0+1},!,t(X,1,Xs).
t(X0,Y0,[p(X0-Y0,V)|Xs]) --> [V],{Y is Y0+1},!,t(X0,Y,Xs).
m(A,B) :- memberchk(A,B).
above(p(X0-Y,V0),p(X-Y,V)) :- X0-X=:=1,m(V0,`S|LJ`),m(V,`S|7F`).
below(p(X0-Y,V0),p(X-Y,V)) :- X-X0=:=1,m(V0,`S|7F`),m(V,`S|LJ`).
left(p(X-Y0,V0),p(X-Y,V)) :- Y0-Y=:=1,m(V0,`S-J7`),m(V,`S-FL`).
right(p(X-Y0,V0),p(X-Y,V)) :- Y-Y0=:=1,m(V0,`S-LF`),m(V,`S-7J`).
link(P1,P2) :- above(P1,P2);below(P1,P2);left(P1,P2);right(P1,P2).
cycle([H|T],Term,End) :-
p(A-B,C), link(H,p(A-B,C)),
\+ (T\=[],p(A-B,C)=Term),
\+ memberchk(p(A-B,C),T),!,
cycle([p(A-B,C),H|T],Term,End).
cycle(Acc,_,End) :- reverse(Acc,End).
solve(File,Part1) :-
phrase_from_file(t(1,1,Xs),File),
retractall(p(_,_)),maplist(assertz,Xs),
p(X-Y,83), cycle([p(X-Y,83)],p(X-Y,83),Bs0),
length(Bs0,N), Part1 is N/2.
cycle/3 takes all the time in my code, the majority of it is spent in the link/2 predicate. Is there something more I can do to above that stands out to you? @CapelliC, I don’t know if there is a more specialised or lazy data structure which would make more sense? Is there some inherent advantage to using a DCG for this?