Из двухтомника Э.Хювёнена и И.Сеппянена."
Определите функцию ДОБАВЬ, прибавляющую к элементам списка данное число"
Я определил функцию получния i-ого элемента списка, а потом конструирую новый, разбирая его по атомам с помощью новой функции и прибавляя к каждому данное число.
Вот что получилось:
(defun get-elem (x num)
(do ()
((= num 0) (car x))
(setq x (cdr x))
(setq num (- num 1))))(defun dobav (x addition)
(do ((i 1 (+ i 1)) (result (+ (get-elem x 0) addition)))
((= i (length x)) result)
(setq result (cons result (+ addition (get-elem x i))))))Но мерзопакость этого способа в том, что он не распатронивает result и туда в конец вставляет новый элемент, а склеивает списки, из-за этого получаются СКОБОЧКИСКОБОЧКИСКОБОЧКИ:
(dobav '(1 35 12 64) 2) // перейдет в ->
(((3 . 37) . 14) . 66)Помогите пожалуйста разобраться , где я перемудрил.
Спасибо.
P.S. знание пока только на уровне элементарных символов.
>Помогите пожалуйста разобраться , где я перемудрил.
Да собственно везде. Достаточно
(defun dobav (L a)
(cond
((null L) nil)
(t (cons (+ a (car L)) (dobav (cdr L) a)))))
(defun addx (ls x)
(do ((curls ls (cdr curls))
res)
((null curls) (nreverse res))
(setf res (cons (+ x
(first curls))
res))))
(addx '(1 2 3) 10)
=> (11 12 13)
Но лучше так:
(defun addx (ls x)
(mapcar (lambda (elt)
(+ elt x))
ls))
А ещё лучше так:
(defun addx (ls x)
(loop :for elt :in ls
:collect (+ x elt)))
Или так=) Тем более если в качестве учебного примера. А вообще, рекурсия в данной ситуации будет медленнее.
Спасибо всем!Прохавал наконец-то, как решить это :)
Немного не по теме, но может знает кто-нибудь.Есть какой-нибудь лисповый или не очень набор упражнений-пятиминуток на рекурсию? Чтобы потренироваться?
Ну, не сильно медленнее (почти одинаково), на самом деле, если поддерживается tail recursion modulo cons.
Попробуй почитать SICP. Там полно всяких задачек.
Так в "Мир Лиспа" как раз же.
Насчёт оптимизации хвостовой рекурсии то понятно. А что такое "modulo cons"?
Ну тут такое дело: как известно в CL это не стандартизировано. По факту sbcl вроде бы применяет. Но с другими реализациями могут быть неожиданные сюрпризы.
vitomsk, ты омич? У меня есть SICP бумажный на русском.
SICP уже у меня появился и активно читается :)Спасибо!