;; Generate combinations. (1.02)

(use-modules (srfi srfi-1))

;; Utility.

(define (pair-map proc l)
  (pair-fold-right (lambda (item init)
                     (cons (proc item) init))
                   '() l))

(define (pair-append-map proc l)
  (apply append (pair-map proc l)))

;; Combinations.

(define (combinations sequence k)
  (if (zero? k)
      (list '())
      (pair-append-map (lambda (rest)
                         (map (lambda (comb)
                                (cons (car rest) comb))
                              (combinations (cdr rest) (- k 1))))
                       sequence)))

;; Show.

(define n 5)
(define a (iota n 1))
(for-each (lambda (k)
            (format #t "~A choose ~A~%" n k)
            (for-each (lambda (c)
                        (format #t " ~A~%" c))
                      (combinations a k)))
          (iota n 1))