Ответ в теме: Извлечь из списка четные и нечетные элементы

      Комментарии к записи Ответ в теме: Извлечь из списка четные и нечетные элементы отключены
#1732

selectOdd(0, [Head|_], [], [Head]):-!.
selectOdd(1, [], [Head,_], [Head]):-!.
selectOdd(_, [], _, []):-!.
selectOdd(_, _, [], []):-!.
selectOdd(0, [Head|Tail1], [_|Tail2], [Head|ResulTail]):-
    selectOdd(1, Tail1, Tail2, ResulTail), !.
selectOdd(1, [_|Tail1], [Head2|Tail2], [Head2|ResulTail]):-
    selectOdd(0, T1, Tail2, ResulTail),!.

Если первый аргумент равен нулю — в результирующий список берется элемент из первого списка, если 1 — то из второго.
Суть в том, что пока списки не кончатся, надо выбирать элементы из них (выбираются элементы в любом случае из обоих списков), элемент одного списка прикреплять к результату, а второго — пропускать. Делается это пока оба списка не кончатся. Вроде бы просто. но есть артефакт — если списки разной длины, и, скажем, нечетный список больше чем четный — то из него надо взять на 1 элемент больше.

По строкам:
1. Если в первом списке один элемент и мы хотим выбирать с него {ноль в первом аргументе} — результат — список из элемента первого списка;
3. Если первый список пуст — результат — пустой список;
5. Если выбираем с первого списка — то первый список разделяем на голову (Head), хвост(Tail1), первый элемент второго списка игнорируем, а то, что от него осталось помещаем в Tail2, рекурсивно обрабатываем Tail1 и Tail2, но при этом вызываем функцию с единицей в первом аргументе (чтобы выбрать элемент из второго списка). Результат рекурсивного вызова поместится в ResulTail, к нему приделаем первый элемент первого списка и вернем как общий результат.

С остальными строками аналогично, но для второго списка.