Позвольте мне показать некоторые улучшения в вашем собственном ответе.
Во-первых, используйте обычное форматирование: нет висячих скобок, тела с отступом в два пробела, другие формы аргументов выровнены.Используйте соответствующие разрывы строк.
(defun is-even-list (lst)
(cond ((null lst) t)
((and (numberp (car lst))
(evenp (car lst)))
(is-even-list (cdr lst)))
(t nil)))
(defun sum-list (lst)
(cond ((null lst) 0)
(t (+ (car lst)
(sum-list (cdr lst))))))
(defun test (lst)
(dotimes (i (list-length lst))
(cond ((not (atom (nth i lst)))
(setf (nth i lst) (test (nth i lst))))))
(cond ((is-even-list lst) (setf lst (sum-list lst)))
((not (is-even-list lst)) (setf lst lst))))
Первая функция проверяет две вещи: каждый элемент является числом и каждый элемент является четным.В этом контексте первое условие в основном означает: нет подсписков.
(defun flat-all-even-p (list)
(and (every #'numberp list)
(every #'even list)))
Вторая функция суммирует список и предполагает, что все элементы являются числами (подсписки будут сигнализировать об ошибке здесь).
(defun sum (list)
(reduce #'+ list))
Третья функция не проверяет , она сумм .Обратите внимание, что он только случайно возвращает ответ, так как setf
возвращает значение, которое он устанавливает.Другая проблема заключается в том, что вы делаете поиск по спискам в цикле, что очень неэффективно.Наконец, вы изменяете список, который вам дали, что удивит вашего абонента.
(defun sum-if-all-even (tree)
(if (listp tree)
(let ((recursed-tree (mapcar #'sum-if-all-even tree)))
(if (flat-all-even-p recursed-tree)
(sum recursed-tree)
recursed-tree))
tree)