(sicp42)sicp3.4.2の20種類を表示する

「'(a b c) '(x y z)」の順序を保ったままの組み合わせ。(20個ある)

(define (my-remove item seq)
  (filter (lambda (x) (not (eq? item x))) seq))

(define (orderd-perm . args)
  (define (each-car-with-nil seqs)
    (fold (lambda (x init)
            (if (null? x)
                init
                (cons (car x) init)))
          '()
          seqs))
  (let ((result '()))
    (let iter ((re '()) (seqs args))
      (let ((next (each-car-with-nil seqs)))
        (if (null? next)
            (push! result (reverse re))
            (dolist (x next) 
              (iter (cons x re)
                    (map (cut my-remove x <>) seqs))))))
    result))
(let1 lst (orderd-perm  '(a b c) '(x y z))
  (print (length lst))
  (for-each print lst))

;; 3:user> 20
;; (a b c x y z)
;; (a b x c y z)
;; (a b x y c z)
;; (a b x y z c)
;; (a x b c y z)
;; (a x b y c z)
;; (a x b y z c)
;; (a x y b c z)
;; (a x y b z c)
;; (a x y z b c)
;; (x a b c y z)
;; (x a b y c z)
;; (x a b y z c)
;; (x a y b c z)
;; (x a y b z c)
;; (x a y z b c)
;; (x y a b c z)
;; (x y a b z c)
;; (x y a z b c)
;; (x y z a b c)