Cyclic Permutation

Started by Jeremy Dunn, July 25, 2008, 10:52:03 AM

Previous topic - Next topic

Jeremy Dunn

Greetings all lispers! I have run across a situation that I am sure some of you have too where one has an expression that involves the repetition of a form that has a cyclic permutation of arguments. For instance, suppose we have



(add (mul (sin A)(sin B))(mul (sin B)(sin C))(mul (sin C)(sin A)))



It is clear we are just cycling through our arguments and wasting a lot of verbiage. I would like to create a function that I will call CYCLIC that enables me to write this something like



(apply add (cyclic '(A B C) '(mul (sin *1)(sin *2))))



In the previous we have a list of the actual values '(A B C) that we want to cycle through and then we have the expression to substitute into. The expression has filler variables *1, *2 ...  I am not sure of how to go about this. Should my expression be a quoted symbol or would it be better to have it as a string to chop apart and evaluate? It is the creation of dummy arguments *1, *2 etc that is puzzling me.

Kazimir Majorinc

#1
This is one possibility:



http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

Kazimir Majorinc

#2
It seems this one does exactly what you want, but it is kinda dirty because it performs analysis of the things like *0 *1, their counting and their conversion into (*** 0), (*** 1). Some of the previous versions is likely better, but it started to look like challenge.


(set 'A 1 'B 2 'C 3)
(set 'cyclic
     (lambda(xp3 L1)
       (let ((maxused 0)
             (i -1)
             (mel1 (map eval L1)))
             (dostring (dummy (string xp3))
               (let ((si (append "*" (string $idx))))
                     (when (find si (string xp3))
                           (set (sym si) (list '*** $idx))
                           (set 'xp3 (expand xp3 (sym si)))
                           (set 'maxused (+ $idx 1)))))
             (map (append (lambda(***)) (list xp3))
                  (map append
                       (map (lambda()
                              (slice (append mel1 mel1)
                                     (inc 'i)
                                     maxused))
                            mel1))))))

(println (apply add (cyclic '(mul (sin *0) (cos *1))
                            '(A B C))))
                       
; -1.1745
           
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.