(GetPermutations '(a b c))
==> ((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
(defun LM:GetPermutations ( l / f1 f2 )
(defun f1 ( l )
(if (cdr l)
(apply 'append (mapcar 'f2 l))
(list l)
)
)
(defun f2 ( a )
(mapcar '(lambda ( b ) (cons a b)) (f1 (vl-remove a l)))
)
(f1 l)
)
(GetPermutations '(a b))
==> ((a b) (b a))
(defun test (l)
(if (cdr l)
(apply 'append
(mapcar '(lambda (a) (mapcar '(lambda (b) (cons a b)) (test (vl-remove a l)))) l)
)
(list l)
)
)
Lee, maybe you'll find something interesting here
http://www.theswamp.org/index.php?topic=14831.15
(defun LM:GetPermutations2 ( l / f1 f2 f3 f4 )
(defun f1 ( l )
(if (cdr l)
(apply 'append (mapcar 'f2 l))
(list l)
)
)
(defun f2 ( a )
(mapcar '(lambda ( b ) (cons a b)) (f1 (f3 a l)))
)
(defun f3 ( x l )
(if l
(if (equal x (car l))
(cdr l)
(cons (car l) (f3 x (cdr l)))
)
)
)
(defun f4 ( l )
(if l (cons (car l) (f4 (vl-remove (car l) l))))
)
(f4 (f1 l))
)
(LM:GetPermutations2 '(A A B))
==> ((A A B) (A B A) (B A A))
(defun t1 (l)
(if (cdr l)
(t3 (apply 'append
(mapcar '(lambda (a b) (mapcar '(lambda (b) (cons a b)) (t1 b))) l (t2 nil l))
) ;_ apply
) ;_ t3
(list l)
) ;_ if
) ;_ defun
(defun t2 (a b)
(if b
(cons (append a (cdr b)) (t2 (append a (list (car b))) (cdr b)))
) ;_ if
) ;_ defun
(defun t3 (l)
(if l
(cons (car l) (t3 (vl-remove (car l) (cdr l))))
) ;_ if
) ;_ defun
test:(t1 '(1 2 3));=>> ((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1))
(t1 '(1 1 1 2));=>> ((1 1 1 2) (1 1 2 1) (1 2 1 1) (2 1 1 1))
Code - Auto/Visual Lisp: [Select]
< ... > )
Thanks Lee. You're right about my function giving duplicates - that's one of the reasons I was searching for a solution. At the time my mind wasn't working :-[ , but your codes have given me some new ideas - thanks again.
I thought a permutation set was based on ALL items in the base set and produced sets based on the item index in the original list rather than the uniqueness of the item. ... but I could be wrong.Code - Python: [Select]
import itertools set_size = 4 data_set = (108, 99, 112, 118, 100, 102, 96, 101) result = list(itertools.permutations(data_set, set_size))
result will be 1680 set lists based on the data-set
Now, for k items selected from a set of n items, this will produce a list of length n!/k!
Hence for your example of selected 4 items from a list of 8 items, you would receive a list of 8!/4! = 1680
Or have I misread your post?
It's a great tool for solving anagrams.
But I can't place your last calc n!/[k!(n-k)!] in the scheme of things. ( what you call combinations)
using n = 8, k=4 result would be 70 sets
((A B) (A C) (B A) (B C) (C A) (C B))
((A B) (A C) (B C))
Hence where combinations are concerned, the subset (A B) == (B A), whereas these are distinct permutations.This would do combinations for me this weekCode - Python: [Select]
import itertools set_size = 2 data_set = [ 'a', 'b', 'c' ] result = list(itertools.combinations(data_set, set_size)) for d in result: print d
interesting discussion.
Python certainly reduces the amount of work & code!
;;Example of using factoradics and combinadics to obtain the list of combinations and permutations in lexicographic order
;;Based on an article of Dr. James McCaffrey in MSDN Magazine
;;Gaston Nunez
;This will get the k-th element of a combination of k items over n
(defun Element(n k m / ans a b x y i)
(setq ans (vlax-make-safearray vlax-vbInteger (cons 0 (- k 1))))
(setq a n)
(setq b k)
(setq x (dual m n k))
(setq i 0)
(while (< i k)
(setq y (vlax-safearray-put-element ans i (largestV a b x)))
(setq x (- x (Choose y b)))
(setq a y)
(setq b (- b 1))
(setq i (+ i 1))
)
(setq i 0)
(while (< i k)
(setq z (- (- n 1)(vlax-safearray-get-element ans i)))
(vlax-safearray-put-element ans i z)
(setq i (+ i 1))
)
(vlax-safearray->list ans)
)
(defun dual(m n k)
(- (- (choose n k) 1) m)
)
(defun LargestV(n k m / v)
(setq v (- n 1))
(while (> (Choose v k) m)
(setq v (- v 1))
)
v
)
;;Calculate n over k without explicit calling to factorials
(defun Choose(n k / delta iMax i)
(cond ((< n k) (setq ret 0))
((= n k) (setq ret 1))
((> n k)
(if (< k (- n k))
(progn
(setq delta (- n k))
(setq iMax k)
)
(progn
(setq delta k)
(setq iMax (- n k))
)
)
(setq ret (+ delta 1))
(setq i 2)
(while (<= i iMax)
(setq ret (/ (* ret (+ delta i)) i))
(setq i (+ i 1))
)))
ret
)
;;get de factoradic decomposition of a number k for groups of n elements
(defun getfactors(order k / j n factors m)
(setq factors (vlax-make-safearray vlax-vbInteger (cons 0 (- order 1))))
(setq m (- order 1))
(setq j 1)
(setq n k)
(while (<= j order)
(vlax-safearray-put-element factors (- order j) (rem n j))
(setq n (/ n j))
(setq j (+ j 1))
)
(vlax-safearray->list factors)
)
;;Get the kth-permutation for a list of integer of length order
(defun get_nth_permut(order k / base i factors permuts index val)
(setq base '())
(setq i 0)
(while (<= i (- order 1))
(setq base (cons i base))
(setq i (+ i 1))
)
(setq base (reverse base))
(setq factors (getfactors order k))
(setq permuts '())
(setq i 0)
(while (< i order)
(setq index (nth i factors))
(setq val (nth index base))
(setq permuts (cons val permuts))
(setq base (vl-remove val base))
(setq i (+ i 1))
)
(reverse permuts)
)
(defun fact(n / ret i)
(setq ret 1)
(if (= n 0) ret
(progn
(setq i n)
(while (>= i 1)
(setq ret (* ret i))
(setq i (- i 1))
)
)
)
ret
)
;;List all the permutations of a given list of integers, tipically (0 1 2 3...)
(defun ListPermutations(order / nperm i)
(setq nperm (fact order))
(setq i 0)
(while (< i nperm)
(print (get_nth_permut order i))
(setq i (+ i 1))
)
(princ)
)
List all the combinations n over k of a list of integer (0 1 2 ...) in goups of k elements
(defun ListCombinations(n k / l i)
(setq l (choose n k))
(setq i 0)
(while (< i l)
(print (element n k i))
(setq i (+ i 1))
)
(princ)
)
;;An example of how to obtain all the strings combinations for a string list.
(defun ListStringComb(strList k / n m i indexlist)
(setq n (length strList))
(setq m (choose n k))
(setq i 0)
(while (< i m)
(setq indexList (element n k i))
(print (getStrList indexList strList))
(setq i (+ i 1))
)
(princ)
)
(defun getStrList(indexlist strlist / x ret)
(setq ret '())
(foreach x indexlist
(setq ret (cons (nth x strlist) ret))
)
(reverse ret)
)
There is a very neat way to obtain the k-th permutation or combination in a lexicographic order, so you can pick exactly the item you want, without calculating all the data.
A little explanation here:http://irenes-coding-blog.blogspot.com/2012/07/factorial-base-numbers-and-permutations.html (http://irenes-coding-blog.blogspot.com/2012/07/factorial-base-numbers-and-permutations.html)
I wrote a function that used integer bit twiddling to arrange the permutations. It was not very speedy for lists sporting more than a dozen items if memory serves. That said, can't remember if it was recursive or iterative. If I wasn't tired I'd revisit - always fun to bash these out - but alas - being 62 isn't what it used to be ...
I think you posted a similar function here (https://www.theswamp.org/index.php?topic=2694.0).
being 62 isn't what it used to be ...now we know the reason for your vast vocabulary... sir ;)
now we know the reason for your vast vocabulary... sir ;)
(not worthy or sarcasm?) Thanks! :laugh:i guess i am not the only one who loves the way you write (both languages of course)
i guess i am the only one who loves the way you write (both languages of course)