Работа с подсписками - Lisp
Формулировка задачи:
Решение задачи: «Работа с подсписками»
(defun task (lst &optional (r (list (car lst))) (tail (cdr lst))) (cond ((null tail) r) (t (task nil (list r (car tail)) (cdr tail))))) ==> task (task '(a b c d e)) ==> (((((a) b) c) d) e)
Объяснение кода листинга программы
В коде определён функцией task с двумя аргументами lst и r.
Функция принимает в качестве начального значения r результат вызова функции car на первом элементе списка lst, а в качестве tail — результат вызова функции cdr на первом элементе списка lst.
Если tail — это nil, то возвращается r.
Если tail — это не nil, то рекурсивно вызывается функция task с аргументами nil, r и tail.
Значит, если мы применим функцию task к списку '(a b c d e), то сначала будет вызван car со значением 'a, затем cdr со значением '(b c d e), затем будет вызван task с аргументами '(b c d e) и '(a), после чего будет вызван car со значением 'b, затем cdr со значением '(c d e), затем будет вызван task с аргументами '(c d e) и '(b a), после чего будет вызван car со значением 'c, затем cdr со значением '(d e), затем будет вызван task с аргументами '(d e) и '(c b a), после чего будет вызван car со значением 'd, затем cdr со значением '(e), затем будет вызван task с аргументами '(e) и '(d c b a), после чего будет вызван car со значением 'e.
Таким образом, результатом работы функции task с аргументом '(a b c d e)' будет '(e)', потому что car возвращает первый элемент списка, а cdr возвращает все остальные элементы списка, начиная со второго.
Если же мы применим функцию task к пустому списку '(), то результатом будет nil, потому что в этом случае рекурсия закончится, так как не будет никаких других элементов списка для обработки.