:- use_module(library(lists)).
% ----------------------------
% задание 1: шелл (седжвик)
% ----------------------------
% shs(+l, -s)
shs(L, S) :-
length(L, N),
sg(N, Gs),
sp(Gs, L, S).
% sg(+n, -gs)
sg(N, Gs) :-
( N =< 1 -> Gs = [1]
; sgk(N, 0, [], Rs),
reverse(Rs, Gs)
).
sgk(N, K, A, Rs) :-
hk(K, H),
hk(K1, H1),
( 3*H1 > N ->
Rs = [H|A]
; sgk(N, K1, [H|A], Rs)
).
% hk(+k,-h)
hk(K, H) :-
).
sp([], L, L).
sp([G|Gs], L, S) :-
gp(G, L, L1),
sp(Gs, L1, S).
% gp(+g,+l,-s)
gp(G, L, S) :-
en(L, 0, Ps),
findall(Ns
, (between
(0, G1
, R
), cls
(Ps
, G
, R
, Ns
)), Bs
), append(Bs, All),
keysort(All, Ss),
vs(Ss, S).
cls(Ps, G, R, Ns) :-
iv(Cs, Vs1, Is1),
ins(Vs1, Vs2),
pi(Is1, Vs2, Ns).
pr
(G
, R
, I
-_
) :- 0 is (I
- R
) mod G
.
en([], _, []).
en([X|Xs], I, [I-X|Ps]) :-
en(Xs, I1, Ps).
iv([], [], []).
iv
([I
-V
|T
], [V
|Vs
], [I
|Is]) :- iv
(T
, Vs
, Is).
pi([], [], []).
pi
([I
|Is], [V
|Vs
], [I
-V
|T
]) :- pi
(Is, Vs
, T
).
vs([], []).
vs([_-V|T], [V|Vs]) :- vs(T, Vs).
% ins(+l,-s)
ins([], []).
ins([X|Xs], S) :- ins(Xs, S1), is1(X, S1, S).
is1(X, [], [X]).
is1(X, [Y|Ys], [X,Y|Ys]) :- X =< Y, !.
is1(X, [Y|Ys], [Y|Zs]) :- is1(X, Ys, Zs).
% ----------------------------
% задание 2: бинарные включения
% ----------------------------
% bis(+l,-s)
bis(L, S) :- bis1(L, [], S).
bis1([], A, A).
bis1([X|Xs], A, S) :-
bin_ins(X, A, A1),
bis1(Xs, A1, S).
% bin_ins(+x,+l,-r)
bin_ins(X, L, R) :-
length(L, N),
bin_pos(X, L, 0, N, P),
sp2(P, L, A, B),
append(A, [X|B], R).
% bin_pos(+x,+l,+lo,+hi,-p)
bin_pos(X, L, Lo, Hi, P) :-
( Lo >= Hi ->
P = Lo
nth0(M, L, V),
( X =< V ->
bin_pos(X, L, Lo, M, P)
bin_pos(X, L, M1, Hi, P)
)
).
% sp2(+k,+l,-a,-b)
sp2(0, L, [], L) :- !.
sp2(K, [X|Xs], [X|A], B) :-
K > 0,
sp2(K1, Xs, A, B).
% cmp(+l,-s1,-s2,-t1,-t2)
cmp(L, S1, S2, T1, T2) :-
tm(shs(L, S1), T1),
tm(bis(L, S2), T2).
tm(G, T) :-
statistics(walltime, [T0,_]),
statistics(walltime, [T1,_]),
% ----------------------------
% задание 3: "слово из домино" (игра)
% ----------------------------
% igra(-w)
igra(w(I, G, R, A)) :-
ds(Ts),
gr(Ts, 7, 42, Ti, T1), ch(Ti, I),
gr(T1, 7, 42, Tg, T2), ch(Tg, G),
gr(T2, 7, 42, Tr, T3), ch(Tr, R),
T3 = Ta, sm(Ta, 42), ch(Ta, A).
% ds(-ts)
ds
(Ts
) :- findall(A
-B
, (between
(0,6,A
), between
(A
,6,B
)), Ts
).
% sm(+ts,-s)
sm([], 0).
sm([A-B|T], S) :-
sm(T, S1),
% gr(+ts,+k,+s,-g,-r)
gr(Ts, 0, 0, [], Ts) :- !.
gr(Ts, K, S, [X|G], R) :-
K > 0, S >= 0,
select(X, Ts, T1),
X = A-B,
gr(T1, K1, S1, G, R).
% ch(+ts,-c)
ch(Ts, C) :-
select(T, Ts, R),
or(T, A-B),
ch1(R, B, [A-B], C).
ch1([], _, A, C) :- reverse(A, C).
ch1(Ts, X, A, C) :-
select(T, Ts, R),
or1(T, X-Y),
ch1(R, Y, [X-Y|A], C).
or(A-B, A-B).
or(A-B, B-A).
or1(A-B, X-Y) :- (X=A, Y=B ; X=B, Y=A).
% ----------------------------
% задание 4 (вариант 2): вставка подсписка с i-го элемента
% ----------------------------
% ins_sub(+sub,+l,+i,-r)
ins_sub(Sub, L, I, R) :-
I >= 1,
sp2(K, L, P, S),
append(P, Sub, T),
append(T, S, R).
Oi0gdXNlX21vZHVsZShsaWJyYXJ5KGxpc3RzKSkuCgolIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KJSDQt9Cw0LTQsNC90LjQtSAxOiDRiNC10LvQuyAo0YHQtdC00LbQstC40LopCiUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKJSBzaHMoK2wsIC1zKQpzaHMoTCwgUykgOi0KICAgIGxlbmd0aChMLCBOKSwKICAgIHNnKE4sIEdzKSwKICAgIHNwKEdzLCBMLCBTKS4KCiUgc2coK24sIC1ncykKc2coTiwgR3MpIDotCiAgICAoIE4gPTwgMSAtPiBHcyA9IFsxXQogICAgOyBzZ2soTiwgMCwgW10sIFJzKSwKICAgICAgcmV2ZXJzZShScywgR3MpCiAgICApLgoKc2drKE4sIEssIEEsIFJzKSA6LQogICAgaGsoSywgSCksCiAgICBLMSBpcyBLICsgMSwKICAgIGhrKEsxLCBIMSksCiAgICAoIDMqSDEgPiBOIC0+CiAgICAgICAgUnMgPSBbSHxBXQogICAgOyAgIHNnayhOLCBLMSwgW0h8QV0sIFJzKQogICAgKS4KCiUgaGsoK2ssLWgpCmhrKEssIEgpIDotCiAgICAoIDAgaXMgSyBtb2QgMiAtPgogICAgICAgIFAyayAgaXMgMSA8PCBLLAogICAgICAgIEsyICAgaXMgSyAvLyAyLAogICAgICAgIFAyazIgaXMgMSA8PCBLMiwKICAgICAgICBIIGlzIDkqUDJrIC0gOSpQMmsyICsgMQogICAgOyAgIFAyayAgaXMgMSA8PCBLLAogICAgICAgIEsyICAgaXMgKEsgKyAxKSAvLyAyLAogICAgICAgIFAyazIgaXMgMSA8PCBLMiwKICAgICAgICBIIGlzIDgqUDJrIC0gNipQMmsyICsgMQogICAgKS4KCnNwKFtdLCBMLCBMKS4Kc3AoW0d8R3NdLCBMLCBTKSA6LQogICAgZ3AoRywgTCwgTDEpLAogICAgc3AoR3MsIEwxLCBTKS4KCiUgZ3AoK2csK2wsLXMpCmdwKEcsIEwsIFMpIDotCiAgICBlbihMLCAwLCBQcyksCiAgICBHMSBpcyBHIC0gMSwKICAgIGZpbmRhbGwoTnMsIChiZXR3ZWVuKDAsIEcxLCBSKSwgY2xzKFBzLCBHLCBSLCBOcykpLCBCcyksCiAgICBhcHBlbmQoQnMsIEFsbCksCiAgICBrZXlzb3J0KEFsbCwgU3MpLAogICAgdnMoU3MsIFMpLgoKY2xzKFBzLCBHLCBSLCBOcykgOi0KICAgIGluY2x1ZGUocHIoRywgUiksIFBzLCBDcyksCiAgICBpdihDcywgVnMxLCBJczEpLAogICAgaW5zKFZzMSwgVnMyKSwKICAgIHBpKElzMSwgVnMyLCBOcykuCgpwcihHLCBSLCBJLV8pIDotIDAgaXMgKEkgLSBSKSBtb2QgRy4KCmVuKFtdLCBfLCBbXSkuCmVuKFtYfFhzXSwgSSwgW0ktWHxQc10pIDotCiAgICBJMSBpcyBJICsgMSwKICAgIGVuKFhzLCBJMSwgUHMpLgoKaXYoW10sIFtdLCBbXSkuCml2KFtJLVZ8VF0sIFtWfFZzXSwgW0l8SXNdKSA6LSBpdihULCBWcywgSXMpLgoKcGkoW10sIFtdLCBbXSkuCnBpKFtJfElzXSwgW1Z8VnNdLCBbSS1WfFRdKSA6LSBwaShJcywgVnMsIFQpLgoKdnMoW10sIFtdKS4KdnMoW18tVnxUXSwgW1Z8VnNdKSA6LSB2cyhULCBWcykuCgolIGlucygrbCwtcykKaW5zKFtdLCBbXSkuCmlucyhbWHxYc10sIFMpIDotIGlucyhYcywgUzEpLCBpczEoWCwgUzEsIFMpLgoKaXMxKFgsIFtdLCBbWF0pLgppczEoWCwgW1l8WXNdLCBbWCxZfFlzXSkgOi0gWCA9PCBZLCAhLgppczEoWCwgW1l8WXNdLCBbWXxac10pIDotIGlzMShYLCBZcywgWnMpLgoKJSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiUg0LfQsNC00LDQvdC40LUgMjog0LHQuNC90LDRgNC90YvQtSDQstC60LvRjtGH0LXQvdC40Y8KJSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgolIGJpcygrbCwtcykKYmlzKEwsIFMpIDotIGJpczEoTCwgW10sIFMpLgoKYmlzMShbXSwgQSwgQSkuCmJpczEoW1h8WHNdLCBBLCBTKSA6LQogICAgYmluX2lucyhYLCBBLCBBMSksCiAgICBiaXMxKFhzLCBBMSwgUykuCgolIGJpbl9pbnMoK3gsK2wsLXIpCmJpbl9pbnMoWCwgTCwgUikgOi0KICAgIGxlbmd0aChMLCBOKSwKICAgIGJpbl9wb3MoWCwgTCwgMCwgTiwgUCksCiAgICBzcDIoUCwgTCwgQSwgQiksCiAgICBhcHBlbmQoQSwgW1h8Ql0sIFIpLgoKJSBiaW5fcG9zKCt4LCtsLCtsbywraGksLXApCmJpbl9wb3MoWCwgTCwgTG8sIEhpLCBQKSA6LQogICAgKCBMbyA+PSBIaSAtPgogICAgICAgIFAgPSBMbwogICAgOyBNIGlzIChMbyArIEhpKSAvLyAyLAogICAgICBudGgwKE0sIEwsIFYpLAogICAgICAoIFggPTwgViAtPgogICAgICAgICAgYmluX3BvcyhYLCBMLCBMbywgTSwgUCkKICAgICAgOyBNMSBpcyBNICsgMSwKICAgICAgICBiaW5fcG9zKFgsIEwsIE0xLCBIaSwgUCkKICAgICAgKQogICAgKS4KCiUgc3AyKCtrLCtsLC1hLC1iKQpzcDIoMCwgTCwgW10sIEwpIDotICEuCnNwMihLLCBbWHxYc10sIFtYfEFdLCBCKSA6LQogICAgSyA+IDAsCiAgICBLMSBpcyBLIC0gMSwKICAgIHNwMihLMSwgWHMsIEEsIEIpLgoKJSBjbXAoK2wsLXMxLC1zMiwtdDEsLXQyKQpjbXAoTCwgUzEsIFMyLCBUMSwgVDIpIDotCiAgICB0bShzaHMoTCwgUzEpLCBUMSksCiAgICB0bShiaXMoTCwgUzIpLCBUMikuCgp0bShHLCBUKSA6LQogICAgc3RhdGlzdGljcyh3YWxsdGltZSwgW1QwLF9dKSwKICAgIGNhbGwoRyksCiAgICBzdGF0aXN0aWNzKHdhbGx0aW1lLCBbVDEsX10pLAogICAgVCBpcyBUMSAtIFQwLgoKJSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiUg0LfQsNC00LDQvdC40LUgMzogItGB0LvQvtCy0L4g0LjQtyDQtNC+0LzQuNC90L4iICjQuNCz0YDQsCkKJSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgolIGlncmEoLXcpCmlncmEodyhJLCBHLCBSLCBBKSkgOi0KICAgIGRzKFRzKSwKICAgIGdyKFRzLCA3LCA0MiwgVGksIFQxKSwgY2goVGksIEkpLAogICAgZ3IoVDEsIDcsIDQyLCBUZywgVDIpLCBjaChUZywgRyksCiAgICBncihUMiwgNywgNDIsIFRyLCBUMyksIGNoKFRyLCBSKSwKICAgIFQzID0gVGEsIHNtKFRhLCA0MiksIGNoKFRhLCBBKS4KCiUgZHMoLXRzKQpkcyhUcykgOi0gZmluZGFsbChBLUIsIChiZXR3ZWVuKDAsNixBKSwgYmV0d2VlbihBLDYsQikpLCBUcykuCgolIHNtKCt0cywtcykKc20oW10sIDApLgpzbShbQS1CfFRdLCBTKSA6LQogICAgc20oVCwgUzEpLAogICAgUyBpcyBTMSArIEEgKyBCLgoKJSBncigrdHMsK2ssK3MsLWcsLXIpCmdyKFRzLCAwLCAwLCBbXSwgVHMpIDotICEuCmdyKFRzLCBLLCBTLCBbWHxHXSwgUikgOi0KICAgIEsgPiAwLCBTID49IDAsCiAgICBzZWxlY3QoWCwgVHMsIFQxKSwKICAgIFggPSBBLUIsCiAgICBTMSBpcyBTIC0gKEEgKyBCKSwKICAgIEsxIGlzIEsgLSAxLAogICAgZ3IoVDEsIEsxLCBTMSwgRywgUikuCgolIGNoKCt0cywtYykKY2goVHMsIEMpIDotCiAgICBzZWxlY3QoVCwgVHMsIFIpLAogICAgb3IoVCwgQS1CKSwKICAgIGNoMShSLCBCLCBbQS1CXSwgQykuCgpjaDEoW10sIF8sIEEsIEMpIDotIHJldmVyc2UoQSwgQykuCmNoMShUcywgWCwgQSwgQykgOi0KICAgIHNlbGVjdChULCBUcywgUiksCiAgICBvcjEoVCwgWC1ZKSwKICAgIGNoMShSLCBZLCBbWC1ZfEFdLCBDKS4KCm9yKEEtQiwgQS1CKS4Kb3IoQS1CLCBCLUEpLgoKb3IxKEEtQiwgWC1ZKSA6LSAoWD1BLCBZPUIgOyBYPUIsIFk9QSkuCgolIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KJSDQt9Cw0LTQsNC90LjQtSA0ICjQstCw0YDQuNCw0L3RgiAyKTog0LLRgdGC0LDQstC60LAg0L/QvtC00YHQv9C40YHQutCwINGBIGkt0LPQviDRjdC70LXQvNC10L3RgtCwCiUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKJSBpbnNfc3ViKCtzdWIsK2wsK2ksLXIpCmluc19zdWIoU3ViLCBMLCBJLCBSKSA6LQogICAgSSA+PSAxLAogICAgSyBpcyBJIC0gMSwKICAgIHNwMihLLCBMLCBQLCBTKSwKICAgIGFwcGVuZChQLCBTdWIsIFQpLAogICAgYXBwZW5kKFQsIFMsIFIpLgo=