Cartesian product / power added by DeeEff on Sat May 13 02:35:05 2017

;; Cartesian Product of list sets

(use srfi-1) ; srfi-1 for append-map, fold-right, iota

(define (prod z xs)
  (map (lambda (x)
         (if (pair? x)
           (cons z x)
           (list z x)))
       xs))

(define (cart-2 zs xs)
  (append-map (cute prod <> xs) zs))

(define (cartesian-product . sets)
  (let ((sets (reverse sets)))
    (fold cart-2 (car sets) (cdr sets))))

(define (repeat xs n)
  (map (lambda _ xs) (iota n)))

(define (cartesian-power xs n)
  (apply cartesian-product (repeat xs n)))