Reputation: 9
What I am trying to do is basically get the some of the list of list, if that makes sense.
What I am trying to achieve is sum([[1, 2], [3, 4], [5, 6]])
. Should return:
Number Of Lists: 3
List 1
3
List 2
7
List 3
11....etc
I can get the Number of Lists which is fairly simple but I'm not quite sure how to loop through the List and then for each List add the number up. Am I making this more complicated than it actually is?
Upvotes: 0
Views: 2152
Reputation: 9686
As long as it's a beginner question, I have made the following code in Visual Prolog, though it's generic and is supposed to work on all major implementations of Prolog:
domains
ilist=integer*
ilistlist=ilist*
predicates
mapsum(ilistlist, ilist, ilist)
reverse(ilist,ilist,ilist)
sum(ilist,integer,integer)
clauses
reverse([],L,L).
reverse([X|Xs], A, R):-
A1 = [X|A],
reverse(Xs, A1, R).
sum([], A, A).
sum([X|Xs], A, R):-
Y = X + A,
sum(XS, Y, R).
mapsum([], A, R):-
reverse(A, [], R).
mapsum([X|Xs], A, R):-
sum(X, 0, Sum),
A1 = [Sum|A],
mapsum(Xs, A1, R).
goal
mapsum([[9,5,3,6],[8,4],[2,7],[]], [], R).
Result is:
R=[23,12,9,0]
1 Solution
This code works for any number of elements in the inner lists and handles empty lists properly.
I think it doesn't make much sense to have lists inside a list, just a list of sums will do.
The asterisk in integer*
in Visual Prolog means that you want the list of integer
s.
In the goal you call the main predicate mapsum
providing it with 3 lists in a list, an empty list (accumulator) and an unbound variable R
; the latter will get the result.
mapsum
in each iteration retrieves the head X
of the list you provided in the goal, and evaluates sum of its (list) elements, then it creates a new list A1
, which's a combination of the accumulator A
and a sum of the head you just evaluated, then it tail-calls itself with the rest of list elements (tail), a new accumulator A1
and the yet unbound variable R
.
When mapsum
approaches the bound condition, when the list (first argument) is empty, it reverses the list, and binds the result of reverse to unbound variable R
.
I think you'll sort out how sum
and reverse
work yourself.
Upvotes: 0
Reputation: 1
If you want to limit the number of built-in predicates you use to just "is":
sum_list([], []).
sum_list([[A,B]|Rest], [Current|RestResult]) :-
Current is A + B,
sum_list(Rest, RestResult).
?- sum_list( [[1,2],[3,4],[5,6]], X ).
X = [3, 7, 11].
Tested in SWI-Prolog.
Upvotes: 0
Reputation: 10672
In SWI-Prolog you can use maplist
and sumlist
;
?- maplist(sumlist, [[1,2], [3,4], [5,6]], Lengths).
Lengths = [3, 7, 11].
Now you can pretty-print Lengths
the way you like.
To learn how maplist
and sumlist
are implemented, just call listing(maplist)
and listing(sumlist)
.
Upvotes: 2