Marius
Marius

Reputation: 35

How to properly iterate through two-dimensions array and sum all the lengths of elements?

I've encountered a problem when trying to iterate through two dimension array and summing up the lengths of all elements inside in prolog.

I've tried iterating through a simple 1D array and result was just as expected. However, difficulties appeared when I started writing the code for 2D array. Here's my code :

findsum(L):-
    atom_row(L, Sum),
    write(Sum).

atom_row([Head|Tail], Sum) :-
    atom_lengths(Head, Sum),
    atom_row(Tail, Sum).
atom_row([], 0).

atom_lengths([Head|Tail], Sum):-
    atom_chars(Head, CharList),
    length(CharList, ThisLenght),
    atom_lengths(Tail, Temp),
    Sum is Temp + ThisLenght,
    write(ThisLenght).
atom_lengths([], 0).

For example, sum of the elements in array [[aaa, bbbb], [ccccc, dddddd]] should be equal to 18. And this is what I get:

?- findsum([[aaa, bbbb], [ccccc, dddddd]]).
436
false.

The output comes from write(ThisLength) line after each iteration.

Upvotes: 1

Views: 232

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477240

Typically it helps (a lot) by splitting the problem into simpeler sub-problems. We can solve the problem, for example, with the following three steps:

  1. first we concatenate the list of lists into a single one-dimension list, for example with append/2;
  2. next we map each atom in that list to the length of that atom, with the atom_length/2 predicate; and
  3. finally we sum up these values, for example with sum_list/2.

So the main predicate looks like:

findsum(LL, S) :-
    append(LL, L),
    maplist(atom_length, L, NL),
    sumlist(NL, S).

Since maplist/3 is a predicate defined in the library(apply), we thus don't need to implement any other predicates.

Note: You can see the implementions of the linked predicates by clicking on the :- icon.

For example:

?- findsum([[aaa, bbbb], [ccccc, dddddd]], N).
N = 18.

Upvotes: 2

Related Questions