1

In a book that deals with mutually orthogonal latin squares, there is an example of implementation of a generator. The part of the code is as follows:

for (int k = 1; k <= numberOfLevels; k++) {
    for (int i = 1; i <= size; i++) {
        for (int j = 1; j <= size; j++) {
            squareArray[k - 1][i - 1,j - 1] = ( k * (i - 1) + (j - 1) ) % size;
        }
    }
}

I wonder, why i=1 and j=1 and then subtracting 1? For k I understand that it is used for multiplication.

3
  • 1
    It is possibly just for consistent with mathematical (textbook) notations for matrices. If the book has a preface or appendix that explains its choice of notations or conventions, please take a look.
    – rwong
    Commented Jun 19, 2017 at 19:38
  • 1
    IMO this is just bad style; in almost every language where arrays are 0-based the idiomatic loop is over the half-closed [0, limit) range. The only excuse here is if this is a straight implementation of an algorithm, which strictly follows some formulas that are 1-based. Commented Jun 19, 2017 at 19:40
  • @MatteoItalia Some languages are not, some code bases are not, and yes some specifications are not. The excuse here is established convention. If this is a context where it's following an established convention then fine. If we're free to chose without being the odd one out then only flagellation justifies this. Icky. Commented Jun 19, 2017 at 19:49

1 Answer 1

2

This is just a choice of code style that perhaps the author thought would be clearer. You could easily rewrite it as

for (int k = 0; k < numberOfLevels; k++) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            squareArray[k][i,j] = ((k+1) * (i + j)) % size;
        }
    }
}

The problem here is that we intuitively think of lists as going from 1 to N, where N is the number of elements. But all arrays in c# are base 0, so we'd have to subtract. You can either subtract when declaring the loop (as I have done) or subtract when using the loop variables (as the original author does).

I think perhaps the author chose to subtract when using the loop variables because there are places where he actually needs the original index number (from 1 to N), e.g. when computing the modulus of the size.

6
  • If you mix 0-based and 1-based indices in closely spaced (or nested) loops, you should rename the variables for clarity: e.g. for (int k1based = 1; k1based <= numberOfLevels...
    – user949300
    Commented Jun 19, 2017 at 19:24
  • Hmm I don't think this is a perfect refactoring. We've gone from starting at squareArray[0][0,0] to starting at squareArray[1][0,0] Commented Jun 19, 2017 at 19:24
  • Oops. Fixed it.
    – John Wu
    Commented Jun 19, 2017 at 19:31
  • Better, now fix the fact that you've added 2 not 1 to the right hand terms (i & j) of the assignment. Commented Jun 19, 2017 at 19:32
  • Nicely done. Oh and @user949300, You really shouldn't mix bases for indices without a darn good reason. Name mangling is more a band-aid than a fix. It's just another symptom of a very bad problem. Commented Jun 19, 2017 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.