From: Dave Weisman
Subject: Re: array subscripts
Date: 
Message-ID: <WEISMAN.92Jul20154259@macaroni.osf.org>
In article <······················@ils.nwu.edu> ·····@ils.nwu.edu (Richard Lynch) writes:

   Newsgroups: comp.lang.lisp
   Path: paperboy.osf.org!think.com!ames!sun-barr!cs.utexas.edu!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!news.ils.nwu.edu!lynch
   From: ·····@ils.nwu.edu (Richard Lynch)
   Subject: array subscripts
   Organization: The Institute for the Learning Sciences
   Date: Tue, 14 Jul 1992 20:31:17 GMT

   Problem:  Given array A, call some function on each possible combination of
   valid subscripts for A.

   A cursory examination of LOOP in CLtL 2 by an old-timer who can't figure out
   an easy way to do this with do, do*, or macros was particularly unrevealing.

   Keep in mind that I *don't* want to call the function on the elements of the
   array, but on the subscripts.

I recently had a similar problem which had to operate on
N-dimensional matricies.  Here's a rough sketch of the algorithm
I used (in emacs lisp).

Dave

======================================================================
;;; This function recurses over the set of all possible 
;;; subscript combinations.

;;; The function "here-is-one" is called for each combination of 
;;; subscripts.

(defun array-thing (current-subscripts
		    max-subscripts 
		    accumulated-subscript-list)

  ;; Decide if we've recursed to the bottom.  If so, invoke the 
  ;; here-is-one function on the subscript list.

  (if (null max-subscripts)
      (here-is-one accumulated-subscript-list)

    ;; Otherwise, loop over this element in the subscript list.

    (dotimes (i (car max-subscripts))
      (array-thing 
       (cdr current-subscripts)
       (cdr max-subscripts)
       (append accumulated-subscript-list (list i))))))

;;; Here is the routine called on each combination of all subscripts.  

(defun here-is-one (this-element)
  (insert "\n"
	  (prin1-to-string this-element)))

;;; Test it

(array-thing '(0 0) '(2 3) nil)
(0 0)
(0 1)
(0 2)
(1 0)
(1 1)
(1 2)
 
--

-- Dave