Pack of consecutive duplicates of list items in prolog lists

I had a problem returning an answer to task 9 P-99: Ninety-nine journal issues :

Set consecutive duplicates of list items in sublists. If the list contains duplicate elements, they must be placed in separate sublists.

An example query with expected results:

?- pack([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
X = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]].

I managed to collect the items in the sublists, but I don’t know how to return the answer.

Here is my code:

pack(X,Y) :- pack(X,[],Y).
pack([H,H|T],Acc,X) :- pack([H|T],[H|Acc],X).
pack([H,H1|T], Acc, X) :- 
    H\=H1, 
    Acc1=[H|Acc],
    append(X, [Acc1], X1),
    pack([H1|T],[],X1).
pack([H], Acc, X) :- 
    Acc1=[H|Acc],
    append(X, [Acc1], X1).

Here the request is executed in trace mode:

?- trace, pack([a,a,a,a,b,c,c],X).
   Call: (6) pack([a, a, a, a, b, c, c], _G986) ? creep
   Call: (7) pack([a, a, a, a, b, c, c], [], _G986) ? creep
   Call: (8) pack([a, a, a, b, c, c], [a], _G986) ? creep
   Call: (9) pack([a, a, b, c, c], [a, a], _G986) ? creep
   Call: (10) pack([a, b, c, c], [a, a, a], _G986) ? creep
   Call: (11) a\=b ? creep
   Exit: (11) a\=b ? creep
   Call: (11) _G1100=[a, a, a, a] ? creep
   Exit: (11) [a, a, a, a]=[a, a, a, a] ? creep
   Call: (11) lists:append(_G986, [[a, a, a, a]], _G1105) ? creep
   Exit: (11) lists:append([], [[a, a, a, a]], [[a, a, a, a]]) ? creep
   Call: (11) pack([b, c, c], [], [[a, a, a, a]]) ? creep
   Call: (12) b\=c ? creep
   Exit: (12) b\=c ? creep
   Call: (12) _G1109=[b] ? creep
   Exit: (12) [b]=[b] ? creep
   Call: (12) lists:append([[a, a, a, a]], [[b]], _G1114) ? creep
   Exit: (12) lists:append([[a, a, a, a]], [[b]], [[a, a, a, a], [b]]) ? creep
   Call: (12) pack([c, c], [], [[a, a, a, a], [b]]) ? creep
   Call: (13) pack([c], [c], [[a, a, a, a], [b]]) ? creep
   Call: (14) _G1127=[c, c] ? creep
   Exit: (14) [c, c]=[c, c] ? creep
   Call: (14) lists:append([[a, a, a, a], [b]], [[c, c]], _G1132) ? creep
   Exit: (14) lists:append([[a, a, a, a], [b]], [[c, c]], [[a, a, a, a], [b], [c, c]]) ? creep
   Exit: (13) pack([c], [c], [[a, a, a, a], [b]]) ? creep
   Exit: (12) pack([c, c], [], [[a, a, a, a], [b]]) ? creep
   Exit: (11) pack([b, c, c], [], [[a, a, a, a]]) ? creep
   Exit: (10) pack([a, b, c, c], [a, a, a], []) ? creep
   Exit: (9) pack([a, a, b, c, c], [a, a], []) ? creep
   Exit: (8) pack([a, a, a, b, c, c], [a], []) ? creep
   Exit: (7) pack([a, a, a, a, b, c, c], [], []) ? creep
   Exit: (6) pack([a, a, a, a, b, c, c], []) ? creep
X = [] .

I assume that at the end of the last rule an additional line should be added in order to somehow associate the result with the input, but I have no idea how to do this.

+3
7

: , X1:

pack([H], Acc, X) :- 
    Acc1=[H|Acc],
    append(X, [Acc1], X1).

:

pack([H], Acc, X) :- append(X, [[H|Acc]], _).

, , , , , , , , . , append/3. , , - .

?- pack([a, a, a, a, b, c, c], X).
X = [] ;
X = [_G704] ;
X = [_G704, _G710] ;
X = [_G704, _G710, _G716] ;
X = [_G704, _G710, _G716, _G722] a

, , , . - .

, , :

pack([X|Unpacked], Packed) :- pack(Unpacked, [[X]], Packed).

pack([H|T], [[H|Acc]|Rest], Packed) :- pack(T, [[H,H|Acc]|Rest], Packed).
pack([X|T], [[Y|Acc]|Rest], Packed) :-
    X \= Y,
    pack(T, [[X],[Y|Acc]|Rest], Packed).
pack([], RPacked, Packed) :- reverse(RPacked, Packed).

append/3 reverse/2 , .

+2

, . "" .

pack([], []).
pack(L, Pack) :-
    pack(L, [], Pack).

pack([X], FrontPack, [[X|FrontPack]]).
pack([X,X|T], FrontPack, Pack) :-
    pack([X|T], [X|FrontPack], Pack).
pack([X,Y|T], FrontPack, [[X|FrontPack]|Pack]) :-
    X \= Y,
    pack([Y|T], [], Pack).

:

| ?- pack([a],X).

X = [[a]] ? ;

no.
| ?- pack([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).

X = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]] ? ;

no
| ?-
+2

, : " ", "" :

pack(X,Y) :- pack(X,[],_,Y).
pack([H,H|T],Acc,X,R) :- pack([H|T],[H|Acc],X,R).

pack([H,H1|T], Acc, X,R) :-
    H\=H1,
    Acc1=[H|Acc],
    append(X, [Acc1], X1),
    pack([H1|T],[],X1,R).

pack([H], Acc, X,R) :-
    Acc1=[H|Acc],
    append(X, [Acc1], X1),
    R = X1.

:

?- pack([a,a,a,a,b,c,c],X).
X = [[a, a, a, a], [b], [c, c]] .

, : , :

pack(L, P) :- pack(L, [], P).

pack([X|Xs], R, P) :-
    add_pack(X, R, R1), pack(Xs, R1, P).
pack([], R, P) :-
    reverse(R, P).

add_pack(X, [[X|Xs]|R], [[X,X|Xs]|R]).
add_pack(X, [R|Rs], [[X],R|Rs]).
add_pack(X, [], [[X]]).

" ": . , , ( ).

edit , , - ( ) , . , /. , Prologgers " , ". ( Prolog - , ), , , .

+2

: - splitlistIfAdj/3 dif/3, reified . !

?- Xs = [a], splitlistIfAdj(dif,Xs,Pss).
Xs  = [ a ],
Pss = [[a]].                                    % succeeds deterministically

?- Xs = [a,a,a,a,b,c,c], splitlistIfAdj(dif,Xs,Pss).
Xs  = [ a,a,a,a,  b,  c,c ],
Pss = [[a,a,a,a],[b],[c,c]].                    % succeeds deterministically

?- Xs = [a,a,a,a,b,c,c,a,a,d,e,e,e,e], splitlistIfAdj(dif,Xs,Pss).
Xs  = [ a,a,a,a,  b,  c,c,  a,a,  d,  e,e,e,e ],
Pss = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]].% succeeds deterministically

:

?- Xs = [A,B], splitlistIfAdj(dif,Xs,Pss), A=1, B=2.
Xs = [1,2], A = 1, B = 2, Pss = [[1],[2]].

?- Xs = [A,B], A=1, B=2, splitlistIfAdj(dif,Xs,Pss). % logically equivalent
Xs = [1,2], A = 1, B = 2, Pss = [[1],[2]].

, , , :

?- Xs = [A,B,C,D], splitlistIfAdj(dif,Xs,Pss).
Xs = [D,D,D,D], Pss = [[D,D,D,D]],           A=B ,     B=C ,     C=D  ;
Xs = [C,C,C,D], Pss = [[C,C,C],[D]],         A=B ,     B=C , dif(C,D) ;
Xs = [B,B,D,D], Pss = [[B,B],[D,D]],         A=B , dif(B,C),     C=D  ;
Xs = [B,B,C,D], Pss = [[B,B],[C],[D]],       A=B , dif(B,C), dif(C,D) ;
Xs = [A,D,D,D], Pss = [[A],[D,D,D]],     dif(A,B),     B=C ,     C=D  ;
Xs = [A,C,C,D], Pss = [[A],[C,C],[D]],   dif(A,B),     B=C , dif(C,D) ;
Xs = [A,B,D,D], Pss = [[A],[B],[D,D]],   dif(A,B), dif(B,C),     C=D  ;
Xs = [A,B,C,D], Pss = [[A],[B],[C],[D]], dif(A,B), dif(B,C), dif(C,D).
+2

SWI-Prolog, ( (lambda)) foldl, :

:- use_module(library(lambda)).

pack(L, PL) :-
L = [A | B],
foldl(\X^Y^Z^(Y = [LY | RY],
          (   member(X, LY)
          ->  Z = [[X | LY]|RY]
          ;   Z = [[X]| [LY | RY]])),
      B, [[A]], RPL),
reverse(RPL, PL).

lambda.pl: http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl

+1

Something like this should work, I think:

%=============================
% pack/2: The public interface
%=============================
pack( []     , []     ) .                   % packing an empty list yields the empty list
pack( [X|Xs] , [Y|Ys] ) :-                  % packing a non-empty list consists of
  construct_run( Xs , [X] , Run , Tail ) ,  % - building a run of length 1 or more from the prefix of the list
  simplify_run( Run , Y ) ,                 % - simplfying it for the special case of a run of length 1
  pack( Tail , Ys )                         % - and then recursively packing whatever is left.
  .                                         % Easy!

%--------------------------
% private helper predicates
%--------------------------

%
% construct_run/4
%
construct_run( []     , Run    , Run    , []     ) .  % the run is complete if the source list is exhausted
construct_run( [X|Xs] , [R|Rs] , [R|Rs] , [X|Xs] ) :- % the run is complete if the head of the source list differs
  T \= R                                              %   from what already in the run
  .                                                   %
construct_run( [X|Xs] , [R|Rs] , Run    , Tail   ) :  % otherwise, 
  T =  R ,                                            % - if the head of the source list matches what already in the run,
  construct_run( Xs , [T,R|Rs] , Run , Tail )         % - we prepend it to the run and recurse down.
  .                                                   %

%
% simplify_run/2 - deal with the special case of run length 1
%
simplify_run( [A]     , A       ) . % run length = 1
simplify_run( [A,B|C] , [A,B|C] ) . % run length > 1
0
source
class find:
    def enter_list(self):
        input_element=raw_input('Enter comma seperated elements -')
        mylist=[ x for x in input_element.split(',')]
        return mylist

    def get_sublist(self,x):
        prev=""
        return_list=[]
        flag=0
        for i in range(len(x)):
            if x[i]!=prev:
                if flag==0:
                    sorted_list=[]
                    sorted_list.append(x[i])
                    prev=x[i]
                else:
                    return_list.append(sorted_list)
                    sorted_list=[]
                    sorted_list.append(x[i])
                    prev=x[i]
            elif x[i]==prev:
                sorted_list.append(x[i])
                prev=x[i]
                flag=1
            if i==len(x)-1:
                return_list.append(sorted_list)
        return return_list
a=find()
create_list=a.enter_list()
print "Entered list : ",create_list
print a.get_sublist(create_list)
0
source

Source: https://habr.com/ru/post/1540563/


All Articles