1

I'm working on a list that contains sublists with 2 elements each. The first element of each sublist is a string and the second one a number.

[ [e, 30], [a, 170], [k, 15], [e, 50] ] 

I want to add all the numbers of each sublist. I tried this one:

sum_fire([H|T],S):-
  flatten(H,L),
  sum_fire(T,S),
  L=[_H1|T1],
  sum(T1,S).

but it's completely wrong, I think. How can i get this to work?

false
  • 10,264
  • 13
  • 101
  • 209
Fillorry
  • 23
  • 3

3 Answers3

2

You just need to break out the string versus the number:

sum_fire( [[_,N]|Tail], Sum ) :-
    sum_fire( Tail, S1 ),
    Sum is N + S1.
sum_fire( [], 0 ).

So I'm using [_,N] instead of H for the head item because I want what's inside (the number N). I don't care about the string for the sum, so it's _.

lurker
  • 56,987
  • 9
  • 69
  • 103
  • the cut it's useless with first argument indexing available. Generally, try to use cuts **only** when necessary to get correct results, and **not** for performance. – CapelliC Jun 09 '13 at 08:21
  • Try to keep things tail recursive when possible.... it's a good habit to get into. –  Jun 09 '13 at 19:20
1

Nothing wrong with @mbratch's code (+1), but I would do it tail-recursively (and cut-free) like so:

sum_fire(L, Sum) :- sum_fire(L, 0, Sum).

sum_fire([[_,N]|T], Acc, Sum) :-
    Acc1 is N + Acc,
    sum_fire(T, Acc1, Sum).
sum_fire([], Sum, Sum).
Daniel Lyons
  • 22,421
  • 2
  • 50
  • 77
0

SWI-Prolog has library(aggregate) for that:

sum_fire(L, S) :-
  aggregate_all(sum(X), member([_,X], L), S).

Another way to get the task done, using library(apply) and library(lists):

?- maplist(nth1(2), [ [e, 30], [a, 170], [k, 15], [e, 50] ], L), sum_list(L, S).
L = [30, 170, 15, 50],
S = 265.
CapelliC
  • 59,646
  • 5
  • 47
  • 90