:- 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).
shellsort_analytical_complexity(N, Complexity) :-
atomic_list_concat(['O(N^(4/3)) ', ' in average case. '], Complexity).
shellsort_complexity(N, NumericComplexity) :-
NumericComplexity
is N
**(4/3).
% Пример использования сортировки Шелла
ex_shs :-
L = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9, 8, 2],
shs(L, S),
length(L, N),
shellsort_analytical_complexity(N, Complexity), % Получаем аналитическое выражение
shellsort_complexity(N, NumericComplexity), %Get a numeric value
format('Сортировка Шелла:~n'),
format(' Исходный список: ~w~n', [L]),
format(' Отсортированный список: ~w~n', [S]),
format(' Оценка сложности: ~w~n', [Complexity]),
format(' Числовая оценка сложности: ~w для N = ~w~n', [NumericComplexity, N]).
% ----------------------------
% задание 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).
binary_insertion_analytical_complexity(N, Complexity) :-
atomic_list_concat(['O(N^2) ', ' in worst/average case. O(N log N) is not possible. '], Complexity).
binary_insertion_complexity(N, NumericComplexity) :-
NumericComplexity
is N
*N
.
% Пример использования бинарных включений
ex_bis :-
L = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9, 8, 2],
bis(L, S),
length(L, N),
binary_insertion_analytical_complexity(N, Complexity), %Get analytic expression
binary_insertion_complexity(N, NumericComplexity),
format('Бинарные включения:~n'),
format(' Исходный список: ~w~n', [L]),
format(' Отсортированный список: ~w~n', [S]),
format(' Оценка сложности: ~w~n', [Complexity]),
format(' Числовая оценка сложности (O(N^2)): ~w для N = ~w~n', [NumericComplexity, N]).
% Запуск всех примеров
run_examples :-
ex_shs,
ex_bis.
?- run_examples.
Oi0gdXNlX21vZHVsZShsaWJyYXJ5KGxpc3RzKSkuCgolIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KJSDQt9Cw0LTQsNC90LjQtSAxOiDRiNC10LvQuyAo0YHQtdC00LbQstC40LopCiUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKJSBzaHMoK2wsIC1zKQpzaHMoTCwgUykgOi0KICAgIGxlbmd0aChMLCBOKSwKICAgIHNnKE4sIEdzKSwKICAgIHNwKEdzLCBMLCBTKS4KCiUgc2coK24sIC1ncykKc2coTiwgR3MpIDotCiAgICAoIE4gPTwgMSAtPiBHcyA9IFsxXQogICAgOyBzZ2soTiwgMCwgW10sIFJzKSwKICAgICAgcmV2ZXJzZShScywgR3MpCiAgICApLgoKc2drKE4sIEssIEEsIFJzKSA6LQogICAgaGsoSywgSCksCiAgICBLMSBpcyBLICsgMSwKICAgIGhrKEsxLCBIMSksCiAgICAoIDMqSDEgPiBOIC0+CiAgICAgICAgUnMgPSBbSHxBXQogICAgOyAgIHNnayhOLCBLMSwgW0h8QV0sIFJzKQogICAgKS4KCiUgaGsoK2ssLWgpCmhrKEssIEgpIDotCiAgICAoIDAgaXMgSyBtb2QgMiAtPgogICAgICAgIFAyayAgaXMgMSA8PCBLLAogICAgICAgIEsyICAgaXMgSyAvLyAyLAogICAgICAgIFAyazIgaXMgMSA8PCBLMiwKICAgICAgICBIIGlzIDkqUDJrIC0gOSpQMmsyICsgMQogICAgOyAgIFAyayAgaXMgMSA8PCBLLAogICAgICAgIEsyICAgaXMgKEsgKyAxKSAvLyAyLAogICAgICAgIFAyazIgaXMgMSA8PCBLMiwKICAgICAgICBIIGlzIDgqUDJrIC0gNipQMmsyICsgMQogICAgKS4KCnNwKFtdLCBMLCBMKS4Kc3AoW0d8R3NdLCBMLCBTKSA6LQogICAgZ3AoRywgTCwgTDEpLAogICAgc3AoR3MsIEwxLCBTKS4KCiUgZ3AoK2csK2wsLXMpCmdwKEcsIEwsIFMpIDotCiAgICBlbihMLCAwLCBQcyksCiAgICBHMSBpcyBHIC0gMSwKICAgIGZpbmRhbGwoTnMsIChiZXR3ZWVuKDAsIEcxLCBSKSwgY2xzKFBzLCBHLCBSLCBOcykpLCBCcyksCiAgICBhcHBlbmQoQnMsIEFsbCksCiAgICBrZXlzb3J0KEFsbCwgU3MpLAogICAgdnMoU3MsIFMpLgoKY2xzKFBzLCBHLCBSLCBOcykgOi0KICAgIGluY2x1ZGUocHIoRywgUiksIFBzLCBDcyksCiAgICBpdihDcywgVnMxLCBJczEpLAogICAgaW5zKFZzMSwgVnMyKSwKICAgIHBpKElzMSwgVnMyLCBOcykuCgpwcihHLCBSLCBJLV8pIDotIDAgaXMgKEkgLSBSKSBtb2QgRy4KCmVuKFtdLCBfLCBbXSkuCmVuKFtYfFhzXSwgSSwgW0ktWHxQc10pIDotCiAgICBJMSBpcyBJICsgMSwKICAgIGVuKFhzLCBJMSwgUHMpLgoKaXYoW10sIFtdLCBbXSkuCml2KFtJLVZ8VF0sIFtWfFZzXSwgW0l8SXNdKSA6LSBpdihULCBWcywgSXMpLgoKcGkoW10sIFtdLCBbXSkuCnBpKFtJfElzXSwgW1Z8VnNdLCBbSS1WfFRdKSA6LSBwaShJcywgVnMsIFQpLgoKdnMoW10sIFtdKS4KdnMoW18tVnxUXSwgW1Z8VnNdKSA6LSB2cyhULCBWcykuCgolIGlucygrbCwtcykKaW5zKFtdLCBbXSkuCmlucyhbWHxYc10sIFMpIDotIGlucyhYcywgUzEpLCBpczEoWCwgUzEsIFMpLgoKaXMxKFgsIFtdLCBbWF0pLgppczEoWCwgW1l8WXNdLCBbWCxZfFlzXSkgOi0gWCA9PCBZLCAhLgppczEoWCwgW1l8WXNdLCBbWXxac10pIDotIGlzMShYLCBZcywgWnMpLgoKCnNoZWxsc29ydF9hbmFseXRpY2FsX2NvbXBsZXhpdHkoTiwgQ29tcGxleGl0eSkgOi0KICAgIGF0b21pY19saXN0X2NvbmNhdChbJ08oTl4oNC8zKSkgJywgJyBpbiBhdmVyYWdlIGNhc2UuICddLCBDb21wbGV4aXR5KS4KCnNoZWxsc29ydF9jb21wbGV4aXR5KE4sIE51bWVyaWNDb21wbGV4aXR5KSA6LQogICBOdW1lcmljQ29tcGxleGl0eSBpcyBOKiooNC8zKS4KCiUg0J/RgNC40LzQtdGAINC40YHQv9C+0LvRjNC30L7QstCw0L3QuNGPINGB0L7RgNGC0LjRgNC+0LLQutC4INCo0LXQu9C70LAKZXhfc2hzIDotCiAgICBMID0gWzMsIDEsIDQsIDEsIDUsIDksIDIsIDYsIDUsIDMsIDUsIDksIDgsIDJdLAogICAgc2hzKEwsIFMpLAogICAgbGVuZ3RoKEwsIE4pLAogICAgc2hlbGxzb3J0X2FuYWx5dGljYWxfY29tcGxleGl0eShOLCBDb21wbGV4aXR5KSwgICUg0J/QvtC70YPRh9Cw0LXQvCDQsNC90LDQu9C40YLQuNGH0LXRgdC60L7QtSDQstGL0YDQsNC20LXQvdC40LUKICAgICAgICBzaGVsbHNvcnRfY29tcGxleGl0eShOLCBOdW1lcmljQ29tcGxleGl0eSksICVHZXQgYSBudW1lcmljIHZhbHVlCiAgICBmb3JtYXQoJ9Ch0L7RgNGC0LjRgNC+0LLQutCwINCo0LXQu9C70LA6fm4nKSwKICAgIGZvcm1hdCgnICDQmNGB0YXQvtC00L3Ri9C5INGB0L/QuNGB0L7Qujogfnd+bicsIFtMXSksCiAgICBmb3JtYXQoJyAg0J7RgtGB0L7RgNGC0LjRgNC+0LLQsNC90L3Ri9C5INGB0L/QuNGB0L7Qujogfnd+bicsIFtTXSksCiAgICBmb3JtYXQoJyAg0J7RhtC10L3QutCwINGB0LvQvtC20L3QvtGB0YLQuDogfnd+bicsIFtDb21wbGV4aXR5XSksCiAgICAgICAgICBmb3JtYXQoJyAg0KfQuNGB0LvQvtCy0LDRjyDQvtGG0LXQvdC60LAg0YHQu9C+0LbQvdC+0YHRgtC4OiB+dyDQtNC70Y8gTiA9IH53fm4nLCBbTnVtZXJpY0NvbXBsZXhpdHksIE5dKS4KCgoKCiUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQolINC30LDQtNCw0L3QuNC1IDI6INCx0LjQvdCw0YDQvdGL0LUg0LLQutC70Y7Rh9C10L3QuNGPCiUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKJSBiaXMoK2wsLXMpCmJpcyhMLCBTKSA6LSBiaXMxKEwsIFtdLCBTKS4KCmJpczEoW10sIEEsIEEpLgpiaXMxKFtYfFhzXSwgQSwgUykgOi0KICAgIGJpbl9pbnMoWCwgQSwgQTEpLAogICAgYmlzMShYcywgQTEsIFMpLgoKJSBiaW5faW5zKCt4LCtsLC1yKQpiaW5faW5zKFgsIEwsIFIpIDotCiAgICBsZW5ndGgoTCwgTiksCiAgICBiaW5fcG9zKFgsIEwsIDAsIE4sIFApLAogICAgc3AyKFAsIEwsIEEsIEIpLAogICAgYXBwZW5kKEEsIFtYfEJdLCBSKS4KCiUgYmluX3BvcygreCwrbCwrbG8sK2hpLC1wKQpiaW5fcG9zKFgsIEwsIExvLCBIaSwgUCkgOi0KICAgICggTG8gPj0gSGkgLT4KICAgICAgICBQID0gTG8KICAgIDsgTSBpcyAoTG8gKyBIaSkgLy8gMiwKICAgICAgbnRoMChNLCBMLCBWKSwKICAgICAgKCBYID08IFYgLT4KICAgICAgICAgIGJpbl9wb3MoWCwgTCwgTG8sIE0sIFApCiAgICAgIDsgTTEgaXMgTSArIDEsCiAgICAgICAgYmluX3BvcyhYLCBMLCBNMSwgSGksIFApCiAgICAgICkKICAgICkuCgolIHNwMigraywrbCwtYSwtYikKc3AyKDAsIEwsIFtdLCBMKSA6LSAhLgpzcDIoSywgW1h8WHNdLCBbWHxBXSwgQikgOi0KICAgIEsgPiAwLAogICAgSzEgaXMgSyAtIDEsCiAgICBzcDIoSzEsIFhzLCBBLCBCKS4KCgpiaW5hcnlfaW5zZXJ0aW9uX2FuYWx5dGljYWxfY29tcGxleGl0eShOLCBDb21wbGV4aXR5KSA6LQogICAgYXRvbWljX2xpc3RfY29uY2F0KFsnTyhOXjIpICcsICcgaW4gd29yc3QvYXZlcmFnZSBjYXNlLiBPKE4gbG9nIE4pIGlzIG5vdCBwb3NzaWJsZS4gJ10sIENvbXBsZXhpdHkpLgoKCmJpbmFyeV9pbnNlcnRpb25fY29tcGxleGl0eShOLCBOdW1lcmljQ29tcGxleGl0eSkgOi0KICAgIE51bWVyaWNDb21wbGV4aXR5IGlzIE4qTi4KCgolINCf0YDQuNC80LXRgCDQuNGB0L/QvtC70YzQt9C+0LLQsNC90LjRjyDQsdC40L3QsNGA0L3Ri9GFINCy0LrQu9GO0YfQtdC90LjQuQpleF9iaXMgOi0KICAgIEwgPSBbMywgMSwgNCwgMSwgNSwgOSwgMiwgNiwgNSwgMywgNSwgOSwgOCwgMl0sCiAgICBiaXMoTCwgUyksCiAgICBsZW5ndGgoTCwgTiksCiAgICBiaW5hcnlfaW5zZXJ0aW9uX2FuYWx5dGljYWxfY29tcGxleGl0eShOLCBDb21wbGV4aXR5KSwgJUdldCBhbmFseXRpYyBleHByZXNzaW9uCiAgICBiaW5hcnlfaW5zZXJ0aW9uX2NvbXBsZXhpdHkoTiwgTnVtZXJpY0NvbXBsZXhpdHkpLAogICAgZm9ybWF0KCfQkdC40L3QsNGA0L3Ri9C1INCy0LrQu9GO0YfQtdC90LjRjzp+bicpLAogICAgZm9ybWF0KCcgINCY0YHRhdC+0LTQvdGL0Lkg0YHQv9C40YHQvtC6OiB+d35uJywgW0xdKSwKICAgIGZvcm1hdCgnICDQntGC0YHQvtGA0YLQuNGA0L7QstCw0L3QvdGL0Lkg0YHQv9C40YHQvtC6OiB+d35uJywgW1NdKSwKICAgIGZvcm1hdCgnICDQntGG0LXQvdC60LAg0YHQu9C+0LbQvdC+0YHRgtC4OiB+d35uJywgW0NvbXBsZXhpdHldKSwKICAgICAgICBmb3JtYXQoJyAg0KfQuNGB0LvQvtCy0LDRjyDQvtGG0LXQvdC60LAg0YHQu9C+0LbQvdC+0YHRgtC4IChPKE5eMikpOiB+dyDQtNC70Y8gTiA9IH53fm4nLCBbTnVtZXJpY0NvbXBsZXhpdHksIE5dKS4KCiUg0JfQsNC/0YPRgdC6INCy0YHQtdGFINC/0YDQuNC80LXRgNC+0LIKcnVuX2V4YW1wbGVzIDotCiAgICBleF9zaHMsCiAgICBleF9iaXMuCiAgICAKICAgICAgPy0gcnVuX2V4YW1wbGVzLiA=