Я пытаюсь написать предикат, который делит список на N частей. Это то, что у меня есть до сих пор.Пролог - разделение списка на N частей
partition(1, List, List).
partition(N, List, [X,Y|Rest]):-
chop(List, X, Y),
member(NextToChop, [X,Y]), %Choose one of the new parts to chop further.
NewN is N-1,
partition(NewN, NextToChop, Rest).
chop(List, _, _):-
length(List, Length),
Length < 2, %You can't chop something that doesn't have at least 2 elements
fail,!.
chop(List, Deel1, Deel2):-
append(Deel1, Deel2, List),
Deel1 \= [],
Deel2 \= [].
Идея состоит в том, чтобы продолжать разделять части списка на две другие части, пока у меня не будет N штук. У меня есть посредственные результаты с этим подходом:
?- partition(2, [1,2,3,4], List).
List = [[1], [2, 3, 4], 1] ;
List = [[1], [2, 3, 4], 2, 3, 4] ;
List = [[1, 2], [3, 4], 1, 2] ;
List = [[1, 2], [3, 4], 3, 4] ;
List = [[1, 2, 3], [4], 1, 2, 3] ;
List = [[1, 2, 3], [4], 4] ;
false.
Так я получаю то, что я хочу, но я его два раза, и есть некоторые другие вещи, присоединенные. При делении на 3 части все еще хуже:
?- partition(3, [1,2,3,4], List).
List = [[1], [2, 3, 4], [2], [3, 4], 2] ;
List = [[1], [2, 3, 4], [2], [3, 4], 3, 4] ;
List = [[1], [2, 3, 4], [2, 3], [4], 2, 3] ;
List = [[1], [2, 3, 4], [2, 3], [4], 4] ;
List = [[1, 2], [3, 4], [1], [2], 1] ;
List = [[1, 2], [3, 4], [1], [2], 2] ;
List = [[1, 2], [3, 4], [3], [4], 3] ;
List = [[1, 2], [3, 4], [3], [4], 4] ;
List = [[1, 2, 3], [4], [1], [2, 3], 1] ;
List = [[1, 2, 3], [4], [1], [2, 3], 2, 3] ;
List = [[1, 2, 3], [4], [1, 2], [3], 1, 2] ;
List = [[1, 2, 3], [4], [1, 2], [3], 3] ;
false.
Другая идея состоит в использовании префикса, но я не знаю, как это будет действительно работать. Чтобы использовать это, я должен позволить Прологу узнать, что ему нужно взять префикс, который не слишком короткий и не слишком длинный, поэтому я не беру префикс, который слишком длинный, поэтому на следующий шаг рекурсии не осталось ничего.
Может ли кто-нибудь указать мне правильное направление?
Небольшое пояснение: предикат должен возвращать все возможности разделения списка в N частях (не считая пустых списков).
Должны ли N части иметь одинаковую длину? должен ли предикат вернуть все возможные способы разделить список на N частей? –
@thanosQR: Предикат должен возвращать все возможные способы разделения списка на N частей. Я добавлю его в ОП. – Mental