# Old habits never die ;-)

Crafting some nice declarative non-procedural code tonight

``````?- columnSums([[1,1],[3,1]], S).
S = [4, 2].
``````
``````columnSums(ListOfRows, ColumnSums):-
Outer = ListOfRows,
Outer = [FirstInner | _],
length(Outer, LengthOuter),
length(FirstInner, LengthInner),
findall(
X,
(
between(1, LengthInner, IndexInner),
findall(
Y,
(
between(1, LengthOuter, IndexOuter),
nth1(IndexOuter, Outer, AnOuter),
nth1(IndexInner, AnOuter, Y)
),
Ys
),
sum_list(Ys, X)
),
ColumnSums
).
``````

Just in case you should need something a bit more efficient, you could try

``````:- use_module(library(clpfd),[transpose/2]).

columnSums(ListOfRows, ColumnSums):-
transpose(ListOfRows,ListOfColumns),
maplist(sum_list,ListOfColumns,ColumnSums).
``````
2 Likes

Love the definition of clpfd:transpose/2 β a cornucopia of maplist/4 and foldl/4!

``````transpose(Ls, Ts) :-
must_be(list(list), Ls),
lists_transpose(Ls, Ts).

lists_transpose([], []).
lists_transpose([L|Ls], Ts) :-
maplist(same_length(L), Ls),  % this is an assertion
foldl(transpose_, L, Ts, [L|Ls], _).

transpose_(_, Fs, Lists0, Lists) :-
maplist(list_first_rest, Lists0, Fs, Lists).

list_first_rest([L|Ls], L, Ls).
``````
1 Like

Thatβs much more compact, thanks

1 Like

Cool! Really elegant.

So elegant.