Я новичок в Прологе и пытаюсь решить это упражнение, но не могу получить желаемый результат. Сжатие списка целых чисел в сжатый список. Список содержит сегменты непрерывных целых чисел. Сегмент длиной более 2 будет закодирован как список [начало, конец], конец является включительно. Если длина не превышает 2, изменений не будет.
Образец:
сжать([3,4,6,7,8,9,10,15,16,17,20,22,23,24,25], CompressedList).
CompressedList = [3, 4, [6,10],[15, 17],20, [22,25]].
Мой неправильный вывод:
CompressedList = [[3, [4]], [6,[10]],[15, [17]],20, [22,[25]]].
Мой код:
compress([], []).
compress([X], [X]).
compress([X, Y | T], [X | CompressedTail]) :-
X + 1 =\= Y,
compress([Y | T], CompressedTail).
compress([X, Y | T], [[X, YLast] | CompressedTail]) :-
compress_consecutive([Y | T], YLast, Next),
compress(Next, CompressedTail).
compress_consecutive([], Last, []) :- Last = [].
compress_consecutive([X], [X], []) :- !.
compress_consecutive([X, Y | T], Last, Next) :-
X + 1 =:= Y,
compress_consecutive([Y | T], Last, Next).
compress_consecutive([X, Y | T], [X], [Y | T]) :- X + 1 =\= Y. ```
@TescellatingHeckler: ты можешь мне помочь?
(Я не получил это сообщение - я думаю, что Stackoverflow не уведомляет, если человек уже не прокомментировал или не ответил)
%compress/2 predicate
% Base case
compress([], []).
% Base case
compress([X], [X]).
compress([X, Y | T], [X | CompressedTail]) :-
X + 1 =\= Y,
compress([Y | T], CompressedTail).
compress([X, Y, Z| T], [X, Y| CompressedTail]) :-
X + 1 =:= Y,
Y + 1 =\= Z,
compress([Z | T], CompressedTail).
compress([X, Y | T], [[X, YLast] | CompressedTail]) :-
compress_consecutive([Y | T], YLast, Next),
compress(Next, CompressedTail).
% Helper predicate to find the last element of a consecutive segment.
compress_consecutive([], Last, []) :- Last = [].
compress_consecutive([X], X, []) :- !.
compress_consecutive([X, Y | T], Last, Next) :-
X + 1 =:= Y,
compress_consecutive([Y | T], Last, Next).
compress_consecutive([X, Y | T], X, [Y | T]) :-
X + 1 =\= Y.
Можно использовать фразу DCG:
% Provides eos//0
:- use_module(library(dcg/basics)).
% End of string
inc_succ --> eos, !.
% Placing into the Remainder string, as "push-back"
inc_succ, [[First, Last]] -->
inc_comp(First, Last),
!,
inc_succ.
% No change
inc_succ, [Next] --> [Next],
inc_succ.
inc_comp(First, Last) --> [First],
inc_comp_(First, Last, 1, Len),
{ Len > 2 }.
inc_comp_(Prev, Last, Len0, Len) --> [Next],
{ Next is Prev + 1,
Len1 is Len0 + 1
},
!,
inc_comp_(Next, Last, Len1, Len).
% Ending is the final choice, to process "greedily"
inc_comp_(Last, Last, Len, Len) --> [].
Результат в swi-прологе:
?- phrase(inc_succ, [1,2,4,5,6,9,10,11,12,13,18,19], R).
R = [1, 2, [4, 6], [9, 13], 18, 19].
@lurker: ты можешь мне помочь?