Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!agate!darkstar.UCSC.EDU!news.hal.COM!decwrl!adobe!machine.mv.us.adobe.com!user
From: jmeehan@mv.us.adobe.com (Jim Meehan)
Subject: Re: a code problem/question
Message-ID: <jmeehan-0701952022050001@machine.mv.us.adobe.com>
Sender: usenet@adobe.com (USENET NEWS)
Organization: Adobe Systems Inc.
References: <3ekkc7$67o@info-server.bbn.com>
Date: Sun, 8 Jan 1995 04:20:29 GMT
Lines: 35

Karsten Poeck's triples don't seem to match what you asked for. I thought
you were looking for all possible pairs.  I saw the problem as producing
all possible bindings between a set of variables, e.g., (a b), and a set
of values, e.g., (1 2 3 4).  If so, this will give you the result:

(defun pc (vars vals)
  (let ((result '()))
    (labels ((f (n in-use)
               (if (= n 0)
                 (push (mapcar #'list  vars in-use) result)
                 (do ((l vals (cdr l)))
                     ((null l))
                   (unless (member (car l) in-use :test #'eq)
                     (f (1- n) (cons (car l) in-use)))))))
      (f (length vars) '()))
    result))

If you care about the exact order of the output, inserting a few calls to
reverse will give the same output you described:

(defun pc (vars vals)
  (let ((result '())
        (vals (reverse vals))
        (vars (reverse vars)))
    (labels ((f (n in-use)
               (if (= n 0)
                 (push (mapcar #'list  vars in-use) result)
                 (do ((l vals (cdr l)))
                     ((null l))
                   (unless (member (car l) in-use :test #'eq)
                     (f (1- n) (cons (car l) in-use)))))))
      (f (length vars) '()))
    (mapcar #'reverse result)))

There are less-consy solutions, no doubt.
