I found this for loop in one of the solutions for Rotating array problem. I am not able to understand this line in the code.
public void RotateArray(int[] nums, int p)
{
var l = nums.Length;
var index = 0;
for (; (p %= l) != 0; l -= p, index += p)
{
for (int i = 0; i < p; i++)
{
var temp = nums[l - p + i + index];
nums[l - p + i + index] = nums[i + index];
nums[i + index] = temp;
}
}
}
this solution is working but not able to get the meaning of the condition in this for loop.
When a
for
loop is confusing, it's sometimes helpful to replace it with awhile
loop, because it has a more ordered depiction of the code execution order, i.e. you can read the code "from top to bottom" rather than having to jump around.A
for
loop with a code ofcan be translated into this
while
:Now let's modify your given code:
We can make it even easier on ourselves by changing a few more things:
p
andl
withplaces
andlength
index
tooffset
(you will see why)while
loop conditiona
andb
for the swap indicesAll this is done to reduce the number of things we have to keep mental track of:
To understand what this does, it's best to look at an example:
What we can see is that after each outer loop, a part of the array has been successfully rotated. This is what
offset
(or originallyindex
) keeps track of.length
(orl
) keeps track of the length of the "rest" that needs a few rotations still.We can also see that the modulus operator
%
is there to make sure that we keep the indices down within the array. It's clear that rotating a length-7 array by 4 would be the same as rotating it by 11, 18, 25, etc., or generally speaking, rotating an array of lengthn
by(c * n) + x
places is the same as rotating by justx
places, which is what the modulus is for.And lastly we see that
offset
/index
is basically just use to shift all activities into the region we are working on.The "difficult" part in understanding lies in proving that after each inner loop, the left "done" part has increased, and understanding why you can calculate the next
places
/p
like this. But mathematically proving this algorithm goes beyond the scope of this post.In general I recommend to create such visualizations as I did, which keep track of variable values and the manipulations. Do it for different values of
length
andplaces
(e.g. 7/5) to get an even better understanding.As others have pointed out, this code is very C#-unlike, where the order in which we value property of code is in general "clarity > brevity > performance" with exceptions only being made where warranted by the application.