Recursion 进行和弦反转的递归

Recursion 进行和弦反转的递归,recursion,lisp,common-lisp,Recursion,Lisp,Common Lisp,我是一名作曲家,通常与Max MSP和OpenMusic合作。 为了将一些工作从OM移植到Max,我刚刚开始学习LISP 我的问题很简单:我想从给定的和弦进行和弦倒转 从(ceg)它需要返回((ceg)(egc)(gce))。这意味着对于3个音符的和弦,我会得到3个倒转,对于n个音符的和弦,我会得到n个倒转 我已经构建了基本功能: (defun if-x-under-y-raise-x (x y) (if (<= x y) (if-x-under-y-raise-x (+ x 12)

我是一名作曲家,通常与Max MSP和OpenMusic合作。 为了将一些工作从OM移植到Max,我刚刚开始学习LISP

我的问题很简单:我想从给定的和弦进行和弦倒转

(ceg)
它需要返回
((ceg)(egc)(gce))
。这意味着对于3个音符的和弦,我会得到3个倒转,对于n个音符的和弦,我会得到n个倒转

我已经构建了基本功能:

(defun if-x-under-y-raise-x (x y)
  (if (<= x y) (if-x-under-y-raise-x (+ x 12) y)  x))

(defun transp (chord)
  (append (cdr chord) 
          (cons (if-x-under-y-raise-x (first chord) (list-max chord 0)) nil)))
和弦
是开始列表。
(renverse'(60 64 67))
应返回3个和弦倒转

欢迎任何帮助。 :-)

循环:

(defun renverse (chord)
  (loop for chord0 = chord then (transp chord0)
        repeat (length chord)
        collect chord0))
递归(具有通常的调用堆栈深度限制):

例如:

CL-USER 19 > (renverse '(60 64 67))
((60 64 67) (64 67 72) (67 72 76))
您也可以使用某种中立的列表处理方式编写它:

(defun mutate-list-n-times-by-fn (list &key (n (length list)) (fn #'identity))
  (loop for l = list then (funcall fn l)
        repeat n
        collect l))

(defun renverse (chord)
  (mutate-list-n-times-by-fn chord :fn #'transp))

(cons X nil)
写得更好,因为
(list X)
renverse
需要一棵树(您正在计算第一个元素的
长度),但在示例中,您给出了一个简单的列表。请您澄清该函数应该做什么。请看:。据我所知,这只是找到一个列表的所有可能排列(
(C E G)
)和一个可能的上/下八度换位后缀。@Linuxios-不完全是;它正在查找列表的所有旋转,带有八进制转置。@是的,这是一个键入错误。我是说“((60 64 67))。非常感谢你,雷纳。你的例子对现在很有帮助,对未来也很有启发。
CL-USER 19 > (renverse '(60 64 67))
((60 64 67) (64 67 72) (67 72 76))
(defun mutate-list-n-times-by-fn (list &key (n (length list)) (fn #'identity))
  (loop for l = list then (funcall fn l)
        repeat n
        collect l))

(defun renverse (chord)
  (mutate-list-n-times-by-fn chord :fn #'transp))