1

i need some help with this, i have a list of this kind:

[[[4,11,9,7],[4,13,8,6],[4,12,10,5]],[[3,12,8,7],[3,11,10,6],[3,13,9,5]],[[2,13,10,7],[2,12,9,6],[2,11,8,5]]] %(is a list with three lists, and inside of each list are other three list)

And i´m trying to get one like this:

[[4,11,9,7],[4,13,8,6],[4,12,10,5],[3,12,8,7],[3,11,10,6],[3,13,9,5],[2,13,10,7],[2,12,9,6],[2,11,8,5]] %(a list with nine lists).

%Currently i have this kind of append, but the output isn't near what i need:

appendL([],[]).  %->base case
appendL([H], H). %->base case
appendL([H,H2|T], [L3|L1]):-
    append(L,L1,L3),
    append(H,H2,L),
    appendL(T, L1).

This one give: [[[4,11,9,7],[4,13,8,6],[4,12,10,5],[3,12,8,7],[3,11,10,6],[3,13,9,5],[2,13,10,7],[2,12,9,6],[2,11,8,5]],[2,13,10,7],[2,12,9,6],[2,11,8,5]]

And you can notice that there is three list that appears two times

false
  • 10,264
  • 13
  • 101
  • 209
  • You're looking into a flattening operation for lists, e.g. [this solution](https://stackoverflow.com/questions/50080759/flatten-list-of-lists-of-lists-into-single-list). – lambda.xy.x May 01 '22 at 14:46

3 Answers3

2

Can use DCG as per Get elements from list of lists

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

seqq([]) --> [].
seqq([Es|Ess]) --> seq(Es), seqq(Ess).

Result in swi-prolog:

% Show first 99 elements of a list
?- set_prolog_flag(answer_write_options, [quoted(true), portray(true), max_depth(100), attributes(portray)]).

?- phrase(seqq([[[4,11,9,7],[4,13,8,6],[4,12,10,5]],[[3,12,8,7],[3,11,10,6],[3,13,9,5]],[[2,13,10,7],[2,12,9,6],[2,11,8,5]]]), L), length(L, Len).
L = [[4,11,9,7],[4,13,8,6],[4,12,10,5],[3,12,8,7],[3,11,10,6],[3,13,9,5],[2,13,10,7],[2,12,9,6],[2,11,8,5]],
Len = 9.

Note: If not wanting to use DCG, then should use a difference list instead of append/2, as per https://www.swi-prolog.org/pldoc/man?predicate=flatten/2

brebs
  • 3,462
  • 2
  • 3
  • 12
0

Guess what, append(K,X). Make the work where;

K=[[[4,11,9,7],[4,13,8,6],[4,12,10,5]],[[3,12,8,7],[3,11,10,6],[3,13,9,5]],[[2,13,10,7],[2,12,9,6],[2,11,8,5]]]
X= [[4,11,9,7],[4,13,8,6],[4,12,10,5],[3,12,8,7],[3,11,10,6],[3,13,9,5],[2,13,10,7],[2,12,9,6],[2,11,8,5]]
0

I'd probably do something like this:

flatten( Xs , Ys ) :- flatten(Xs,Ys,[]) .

flatten( []    ,    Fs  , Fs ) .
flatten( [H|T] ,    Fs  , F1 ) :- nested(H), !, flatten(H,Fs,F0) , flatten(T,F0,F1) .
flatten( [H|T] , [H|F0] , F1 ) :-                                  flatten(T,F0,F1) .

nested( [ [_|_] | _ ] ) .

That lets you say things like this:

L = [
      [
        [a] ,
        [b]
      ],
      [
        [
          [c] ,
          []  ,
          [d] ,
          [
            [e]
          ],
          [g]
        ]
      ]
    ],
flatten( L , F ) .

And get

F = [
      [a] ,
      [b] ,
      [c] ,
      []  ,
      [d] ,
      [e] ,
      [g]
    ]
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • The requirement is to "flatten" by 1 level, rather than flatten completely into a plain list. – brebs May 03 '22 at 07:03
  • @brebs — not so. He starts with a list of 3 lists, each of which contains 3 lists — `[ [ [a],[b],[c] ], [ [d],[e],[f] ], [ [g],[h],[i] ] ]` — and the O.P. wishes to reduce that to a simple list of 9 lists: `[ [a], [b], [c], [d], [e], [f], [g], [h], [i] ]`. This code meets the requirement (for any depth of nested lists-of-lists). – Nicholas Carey May 03 '22 at 20:42