Реверс во всех подсписках четных уровней. Нечетные не трогать - Lisp
Формулировка задачи:
Здравствуйте!
Необходимо создать функцию принимающую в качестве своего аргумента любой многоуровневый список вида
(a b (c d (e f (g h)) i) (j (k (l m n))))
образовать результирующий список вида
(a b (i (e f (h g)) d c) ((k (n m l)) j))
Будьте добры и подскажите хоть идеей, хоть кодом. Реверс могу делать на всех уровнях, но определять уровень вложенности как-то не пойму как. Вообще идеи не приходят.
Решение задачи: «Реверс во всех подсписках четных уровней. Нечетные не трогать»
textual
Листинг программы
(defun rev-ev-lev (w &optional (v 1)) (when w (mapcar #'(lambda (a) (if (listp a) (rev-ev-lev a (1+ v)) a)) (if (evenp v) (reverse w) w)))) > (rev-ev-lev '(a b (c d (e f (g h)) i) (j (k (l m n))))) (A B (I (E F (H G)) D C) ((K (N M L)) J))
Объяснение кода листинга программы
В данном коде определён функционал для обратного преобразования элементов списка, основанный на их уровне чётности.
(defun rev-ev-lev (w &optional (v 1))
— определение функцииrev-ev-lev
, которая принимает два аргумента:w
— список, который необходимо изменить, иv
— переменная, отвечающая за уровень глубины вложенности списка. Значениеv
по умолчанию равно 1.(when w (mapcar)
— проверка на отсутствие пустого спискаw
. Еслиw
не пустой, то выполняется следующая часть кода.#'(lambda (a) (if (listp a)
— анонимная функция, которая рекурсивно вызывает себя для каждого элемента спискаa
. Если элемент является списком, то вызывается рекурсивноrev-ev-lev
с аргументамиa
иv+1
.(if (evenp v) (reverse w) w)
— проверка значения переменнойv
на чётность. Еслиv
— чётное число, то возвращается списокw
, перевёрнутый с помощью функцииreverse
.(rev-ev-lev '(a b (c d (e f (g h)) i) (j (k (l m n)))))
— вызов функцииrev-ev-lev
с аргументами(a b (c d (e f (g h)) i)
и(j (k (l m n)))
. В результате получаем(A B (I (E F (H G)) D C) ((K (N M L)) J)
. Таким образом, данный код реверсирует элементы списка, основываясь на их уровне чётности.