Guest User

Calculating permutations using Steinhaus–Johnson–Trotter alg

a guest
May 18th, 2012
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.08 KB | None | 0 0
  1. (defun permutations (function vector)
  2.   (declare (type function function))
  3.   (declare (type vector vector))
  4.   (declare (optimize (speed 3) (safety 0)))
  5.   (let* ((vector-length (length vector))
  6.      (ordered
  7.       (do ((i 0 (1+ i))
  8.            (result (make-hash-table)))
  9.           ((= i vector-length)
  10.            (return result))
  11.         (setf (gethash (aref vector i) result) i)))
  12.      (directions
  13.       (make-array
  14.        vector-length
  15.        :element-type 'function
  16.        :initial-element #'1-)))
  17.     (labels ((elt< (a b)
  18.            (< (gethash a ordered)
  19.           (gethash b ordered))))
  20.       (setf (aref directions 0) #'identity)
  21.       (do ((i 1 (1+ i))
  22.        (a 1)
  23.        (b 1))
  24.       ((= b (1+ vector-length)))
  25.     (when (= i a)
  26.       (setf b (1+ b) a (* a b)))
  27.     (if (= i 1) (funcall function vector)
  28.         (do* ((n 0 (1+ n))
  29.           (sign (aref directions n) (aref directions n))
  30.           (element (aref vector n) (aref vector n))
  31.           (largest) (largest-index)
  32.           (swap) (swap-index))
  33.          (nil)
  34.           (when (and (not (eq sign #'identity))
  35.              (or (null largest)
  36.                  (elt< largest element)))
  37.         (setf largest element
  38.               largest-index n
  39.               swap-index (funcall sign n)
  40.               swap (aref vector swap-index)))
  41.           (when (= n (1- vector-length))
  42.         (setf (aref vector swap-index) largest
  43.               (aref vector largest-index) swap
  44.               sign (aref directions swap-index)
  45.               (aref directions swap-index) (aref directions largest-index)
  46.               (aref directions largest-index) sign)
  47.         (when (or (= swap-index 0)
  48.               (= swap-index (1- vector-length))
  49.               (elt< largest
  50.                 (aref vector
  51.                       (funcall (aref directions swap-index)
  52.                            swap-index))))
  53.           (setf (aref directions swap-index) #'identity))
  54.         (funcall function vector)
  55.         (dotimes (j vector-length)
  56.           (cond
  57.             ((and (< j swap-index)
  58.               (elt< largest (aref vector j)))
  59.              (setf (aref directions j) #'1+))
  60.             ((and (> j swap-index)
  61.               (elt< largest (aref vector j)))
  62.              (setf (aref directions j) #'1-))))
  63.         (return))))))))
  64.  
  65. (permutations
  66.  #'(lambda (x)
  67.      (format t "~{~s ~}~&" (coerce x 'list)))
  68.  #(1 2 3 4))
Advertisement
Add Comment
Please, Sign In to add comment