JennyToy
JennyToy

Reputation: 628

nested loops with accumulation in scheme

I would like to create a scheme vector with dimensions n^{2} by n^{2} (so if n=4 this is a 16 by 16 matrix, if n=5 it is a 25 by 25 matrix) where each element is an integer given by the following (the value of the element has to be always between 1 and n*n)

x=0
for i=0 to n-1 
  for j=0 to n-1
    for k=0 to n*n-1
       vector[n(i - 1) + j + k]= x (mod n*n)+ 1 
       x = x+1
    x= x + n 
  x=x+1

I started down the following path but I am not sure how to do the x accumulation in scheme

(define (generate-vector n)
   (define w (* n n))
   (for*/vector  ([row (in-range n)]
              [col (in-range n)]
              [k (in-range w)])
              ; TO DO))

Upvotes: 0

Views: 206

Answers (3)

Michael Vehrs
Michael Vehrs

Reputation: 3363

Based on your comments rather than the original question, I think you might be looking for something like this:

(define generate-vector
  (lambda (n)
    (let ((template (iota (* n n) 1)))
      (let loop ((todo template)
                 (done '())
                 (result template))
        (if (= 1 (length todo))
            (list->vector result)
            (let* ((head (car todo))
                   (tail (cdr todo))
                   (next (append done (list head))))
              (loop tail
                    next
                    (append result tail next))))))))

iota is defined by SRFI-1.

Upvotes: 1

soegaard
soegaard

Reputation: 31147

Here is an almost literal translation of your pseudo-code:

(define (generate-vector n)
  (define n^2 (* n n))
  (define v (make-vector n^2))
  (define x 0)
  (for ([i n])
    (for ([j n])
      (for ([k n^2])
        (vector-set! v (+ (* n i) j) (+ (modulo x n^2) 1))
        (set! x (+ x 1)))
      (set! x (+ x n)))
    (set! x (+ x 1)))
  v)

(generate-vector 3)

Note 1: (- i 1) was changed to i (otherwise you get negative indices when i=0.

Note 2: I omitted the +k since that leads to indices too large.

Upvotes: 1

Óscar López
Óscar López

Reputation: 236004

If I understood correctly, you want an n x n vector, where each element is a different integer starting from 1. Try this:

(define (generate-vector n)
  (for/vector ([i (in-range n)])
    (build-vector n (lambda (j) (+ (* n i) j 1)))))

For example:

(generate-vector 3)
=> '#(#(1 2 3) #(4 5 6) #(7 8 9))

Upvotes: 1

Related Questions