(defun rand (min max)

(+ (random (1+ (- max min))) min))


(defun cpair (a b)

(unless (eql a b) (list (cons a b) (cons b a))))


(defun cgraph(n min max)

(apply #'append (loop repeat n collect (cpair (rand min max) (rand min max)))))


(defun collect-car (what list)

(remove-if-not (lambda (x) (eql (car x) what)) list))


(defun graph-connected (node list)

(let ((visited nil))

(labels ((traverse (node) unless (member node visited) (push node visited) (mapc (lambda (tnode) (traverse (cdr tnode))) (collect-car node list)))))

(traverse node)) visited))


(defun graph-find (nodes list)

(let ((tnode nil)) 

(labels ((node-find (nodes)

   (let* ((connected (graph-connected (car nodes) list))

          (unconnected (set-difference nodes connected)))

   (push connected tnode) (when unconnected (graph-find unconnected)))))

(graph-find nodes)) tnode))


(defun graph-connect (nodes)

(when (cdr nodes) (append (cpair (caar nodes) (caadr nodes)) (graph-connect (cdr nodes)))))


(defun graph-connect-all (nodes list)

(append (graph-connect (graph-find nodes list)) list))