Reputation: 55
I want to rearrange a list according to their length of sublists from short to long.
The expect output is:
rearrange([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]],X).
X=[[c],[s],[a,b],[d,s],[a,b,c],[d,d,d],[d,s,s,a]].
My idea is that to calculate each length first and then do rearrangement. What I have done so far is to collect the number of sublist whose length is equal to the first sublist using the pattern [length-number].
count([],[0-0]).
count([A|B],[L-N]):-
length(A,L),
same_length(B,L,M),
N is M+1.
same_length([],_,0).
same_length([A|B],L,N) :-
( length(A,L)->
same_length(B,L,M),
N=M+1
; same_length(B,L,N)
).
The count(LIST,X) output is as followed:
21 ?- count_slot([[2],[3],[4],[2,3,4]],X).
X = [1-3].
But the expected output is [1-3,3-1], I don't know how to deal with the rest sublist(remove one by one??) and rearrange them according to the pattern [1-3,3-1].
Can somebody help? Thanks in advanced.
Upvotes: 1
Views: 395
Reputation: 40768
In such cases, keysort/2
often comes in handy. For example:
lists_ascending(Lists0, Lists) :-
maplist(list_with_length, Lists0, LLs0),
keysort(LLs0, LLs),
pairs_values(LLs, Lists).
list_with_length(List, L-List) :- length(List, L).
Example query and its result:
?- lists_ascending([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]], Ls).
Ls = [[c], [s], [a, b], [d, s], [a, b, c], [d, d, d], [d, s, s, a]]
EDIT: The following predicate, which uses the code above, sorts in the way you outline in the comment below, which is by the number of appearances of sublists of the same length:
lists_ascending_appearences(Lists0, Lists) :-
maplist(list_with_length, Lists0, LLs0),
keysort(LLs0, LLs1),
group_pairs_by_key(LLs1, LLs2),
pairs_values(LLs2, Lists1),
lists_ascending(Lists1, Lists2),
append(Lists2, Lists).
Example query and its result:
?- lists_ascending_appearences([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]], Ls).
Ls = [[d, s, s, a], [c], [s], [a, b], [d, s], [a, b, c], [d, d, d]].
Upvotes: 1