I am writing a solution to working out distances between numbers in a list using recursion, but have been struggling with getting the intended output.
I am trying to get a list of lists into a single list, but attempts at using flatten and append/2 aren't working. I have tried for hours, and keep going around in circles, can someone tell me what i'm doing wrong please?
:- use_module(library(clpfd)).
difference([],_,[]).
differwnce([L|Ls],X,[DST|Ds]) :-
DST #= abs(X - L),
difference(Ls,X,Ds).
differences[],[]).
differences([L|Ls], [DST|Tail]) :-
difference(Ls,X,DST),
differences(Ls, Tail).
Here is the intended input and output:-
?- differences([1,2,4,9],Ds).
Ds = [1,3,8,2,7,5].
Current Output:
Ds = [[1,3,8],[2,7],[5],[]].
You can convert your distances/3
predicate into a distances/4
predicate that returns a list tail for the elements that will follow, effectively using an open list:
:- use_module(library(clpfd)).
distances([], _, Tail, Tail).
distances([BN| Bs], B, [DST| Ds], Tail) :-
DST #= abs(B - BN),
distances(Bs, B, Ds, Tail).
triangle([], []).
triangle([BN| Bs], Ds) :-
distances(Bs, BN, Ds, Tail),
triangle(Bs, Tail).
Sample call:
?- triangle([1,2,4,9], Ds).
Ds = [1, 3, 8, 2, 7, 5].
To better understand this solution consider the results of the following query:
?- distances([2,4,9], 1, Ds, Tail).
Ds = [1, 3, 8| Tail].
This solution is more efficient than calling predicates such as append/2
or flatten/3
at the end.
P.S. If you still need a distances/3
predicate to use elsewhere, you can define it easily:
distances(Bs, B, Ds) :-
distances(Bs, B, Ds, []).
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
seqq([]) --> [].
seqq([Es|Ess]) -->
seq(Es),
seqq(Ess).
?- phrase(seqq([[1,3,8],[2,7],[5],[]]), Es).
Es = [1,3,8,2,7,5].
Why not use the library predicate append/2
like so?
?- append([[1,3,8],[2,7],[5],[]], Xs).
Xs = [1,3,8,2,7,5].