I have a functor that calculate the Manhattan distance in a N-puzzle domain of a single tile:
distanzaTile(Stato, Pos, Dis) :-
dim(D),
nth0(Pos, Stato, Elem),
Elem == v,
Y is floor(abs((9 - (Pos + 1))/D)),
X is mod(abs(9 - (Pos + 1)), D),
Dis is X+ Y.
!.
distanzaTile(Stato, Pos, Dis) :-
dim(D),
nth0(Pos, Stato, Elem),
Y is floor(abs((Elem - (Pos + 1))/D)),
X is mod(abs(Elem - (Pos + 1)), D),
Dis is X+ Y.
where Stato
is an array, Pos
is the current position in the array taken into account, Dis
is the actual result.
Now, I have to cycle through all the elements of Stato
and sum all the Dis
s.
Thinking imperative I'd go for a for
cycle. How to achieve something similar recursively?
I used Stato
as input and as counter as follow:
ricorri(_, [], _, A, A).
ricorri(Stato, [_|T], Pos, In, Out) :-
distanzaTile(Stato, Pos, Dis),
Pos2 is Pos + 1,
In2 is In + Dis,
ricorri(Stato, T, Pos2, In2, Out).
Hope it may help someone.