Advent of code 2023

Here comes a 6-th way to solve it and maybe some insight?

You can also use CHR to implement mode directed tabling. Here is a
code that solves part 1 day 21. Internally I named it solutionchr.p, since
I derived it from my mode directed tabling solution.p:

:- use_module(library(chr)).
:- chr_constraint go/1, dist/4, neigh/2.

go(N) ==> garden(X, Y, 0'S),
   neigh(0,1), neigh(1,0), neigh(0,-1), neigh(-1,0),
   dist(X, Y, N, 0).

dist(X,Y,N,D1) \ dist(X,Y,N,D2) <=> D1 =< D2 | true.

dist(H, J, N, L), neigh(DX, DY) ==> L < N, X is H+DX, Y is J+DY,
   garden(X, Y, C), C \= 0'# | R is L+1, dist(X, Y, N, R).

count(N, X) :-
   go(N),
   aggregate_all(count,
        (current_chr_constraint(dist(_,_,N,K)), (N+K) mod 2 =:= 0), X).

But I am not a frequent CHR user, so maybe this is not the
best way to write it with CHR. But it seems to work fine.
Here the result for the tester 11x11 from the part 1 description:

?- count(6, X).
X = 16

Edit 27.12.2023
Credits go to this SWI-Prolog discourse thread, where it was made the
impression that for the Dijkstra algorithm some CHR with priorities
would be needed, or alternatively that we would want to have

a fibonacci heap. Well this is even not wrong, if one wants to
remodel some common strategy how Dijkstra algorithm proceeds,
that allows early stopping for the shortes path. But if you compute

distances everywhere you don’t aim at early stopping, you anyway
need to exhaust. You can inspect my code above, I basically used the
same rules as presented Dijkstra CHR thread but without any priorities,

and since the min operator on an integer lattice it is used, I tend
to claim that any operation order saturation will give the same.