Это решение, в котором не используются функции с более чем одним параметром (за исключением =
, +
, *
, logand
, ash
; Отметим также, что logand
и ash
всегда имеют константу в качестве второго параметра, чтобы они могли также реализуются как унарные функции).
Идея состоит в том, чтобы «скрыть» два параметра, необходимые для очевидного рекурсивного подхода в одном целом с использованием нечетных/четных битов.
(defun pair (n)
(if (= n 0)
0
(+ (* 3 (logand n 1))
(ash (pair (ash n -1)) 2))))
(defun pair-first (p)
(if (= p 0)
0
(+ (logand p 1)
(ash (pair-first (ash p -2)) 1))))
(defun pair-second (p)
(pair-first (ash p -1)))
(defun subsec (p)
(if (= 2 (logand p 2))
(- p 2)
(+ (logand p 1) 2 (ash (subsec (ash p -2)) 2))))
(defun pairpow (p)
(if (= (pair-second p) 1)
(pair-first p)
(* (pair-first p)
(pairpow (subsec p)))))
(defun f (n)
(pairpow (pair n)))
Нет разумного использования, конечно; но забавное упражнение действительно.
Если вы хотите умножить числа в alist, тогда лучше использовать REDUCE вместо APPLY. APPLY может поддерживать только списки максимальной длины CALL-ARGUMENTS-LIMIT. –