(defun f (A |a| B)
  (let* ((i (position |a| A))
         (A2 (nconc (subseq A i) (subseq A 0 i))))
    (sort (copy-seq B) (lambda (x y) (< (position x A2) (position y A2))))))

(defun g (A |a| B)
  (let ((i (position |a| A)))
    (loop with result = '()
          for x in (nconc (subseq A i) (subseq A 0 i))
          when (member x B)
          do (loop repeat (count x B) do (push x result))
          finally (return (nreverse result)))))

(dolist (fn '(f g))
  (format t "~S:~%" fn)
  (loop for args in '(((2 3 5 7 9) 2 (9 2 5))
                      ((2 3 5 7 9) 9 (9 2 5))
                      ((2 3 5 7 9) 5 (9 2 5))
                      ((2 3 5 7 9) 3 (9 2 5 5 2)))
        do (format t "~{A = ~S, a = ~S, B = ~S~} ~42T =>  ~S~%"
                   args
                   (apply fn args)))
  (terpri))

(defmacro b (n exp)
  `(progn
     (write-line "==================================================")
     (time (loop repeat n do ,exp
                 finally (format t "Evaluated ~S ~D times." ',exp ,n)))))

(compile 'f)
(compile 'g)
(let ((n 80000))
  (b n (f '(2 3 5 7 9) 9 '(7 3 3 5 2 2 2 7 7 5 3 9)))
  (b n (g '(2 3 5 7 9) 9 '(7 3 3 5 2 2 2 7 7 5 3 9))))
