首先,一个完成一半工作的谓词:重新排序列表,以便每隔一个元素被挑选出来并附加到后面,保持顺序:
untangle([], []).
untangle([X|Xs], [X|Ys]) :-
untangle_1([X|Xs], [X|Ys], Bs, Bs).
% The rest of the Untangled is the list at the back;
% the list at the back is now empty
untangle_1([], Back, Back, []).
% Keep elements in odd positions at the front
untangle_1([X|Xs], [X|Untangled], Back, Bs) :-
untangle_2(Xs, Untangled, Back, Bs).
% Same as above
untangle_2([], Back, Back, []).
% Move elements in even positions to the back
untangle_2([X|Xs], Untangled, Back, [X|Bs]) :-
untangle_1(Xs, Untangled, Back, Bs).
这与此答案interwine/3
中定义的非常相似。它不是为“解压缩”元素使用两个列表,而是将它们放在同一个列表的前面和后面。
现在你需要的是洗牌,否则将附加到后面的元素:
shuffle([], []).
shuffle([X|Xs], Shuffled) :-
untangle_1([X|Xs], Shuffled, Back, Bs),
shuffle(Bs, Back).
我理解正确吗?
?- shuffle([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z], S), write(S).
[a,c,e,g,i,k,m,o,q,s,u,w,y,b,f,j,n,r,v,z,d,l,t,h,x,p]
S = [a, c, e, g, i, k, m, o, q|...].
您还会注意到这shuffle/2
在 、 和 模式shuffle(+List, -Shuffled)
下shuffle(-List, +Shuffled)
有效shuffle(?List, ?Shuffled)
。据我所知,它在语义上是相同的(并且在实现上几乎相同)与 false 的解决方案。