The Magic Increment or moving array elements.

In this tutorial I will explain how to create a function that will move any array element from it's present position to any new position in given array; the logic behind it, pseudocode as well as it's implementation in various programming languages such as C/C++, ActionScript, PHP and JavaScript.

To understand this tutorial you will require basic knowledge of almost any programming language and calculus.

Logic.

Let us assume that we have an array with some sort of elements in it and that we need to move one of them to a new position.

To make it easier to understand let us also assume that the array is linear or one-dimensional.

Firstly to move an element we will need to know two parameters: index of element to be moved and destination index. We will refer to them as indexFrom and indexTo respectively.

Now let's look closer at the process of moving itself. If we imagine our array as one-dimensional sliding puzzle it becomes obvious that we need to have an empty space (missing piece) to be able to move anything, thus let us "save" or make a copy of the element at indexFrom and consider this elemnt to be an "empty spot" in later thinking.

Now we need to move our "empty spot" to a new position indicated with indexTo. In case of the sliding puzzle we would place a finger on the first element neighbouring the "empty spot" in the direction of our movement and move it to the "empty spot". Then we would repeat the above until the "empty spot" reaches indexTo. But how do we find out wich way do we move?

We can use a condition operator to check if indexTo is larger than indexFrom. If this condition evaluates as true we move to the right, else we move left. But there is another way that makes the whole process less messy.


The magic increment.

Since the only difference between left and right element shift is the direction, we can extract it in a form of -1 or +1 from our given data, and use it as a multiplication factor that will define direction of our motion or shift. We'll call it the magicIncremnt.

That's how it works. Consider next mathematical equation:










Technicaly this equation extracts direction component from a vector of our movement. There is no quantitative difference between numerator and denominator, only sign is different, therefore we'll get +1 if indexTo is larger than indexFrom and vice versa.

The denominator can be substituted with absolute value operator usualy known as abs().

Note that indexFrom can not equal indexTo in which case you'll get devision by zero. And then move to the same position is not really a move at all in case of array manipulation.

Using magicIncrement alows us to implement the shift of elements in the array (the relocation of "empty spot" in our sliding puzzle) as for() loop of following type:

For each Element starting from indexFrom move Element displaced by magicIncrement to Element without displacement until indexTo is reached.

After this the only thing left to be done is to place previously saved element copy at indexTo position.


Pseudocode.

//find magic increment
magicIncrement = (indexTo - indexFrom) / abs(indexTo - indexFrom);

//copy target element
targetElement = targetArray [indexFrom];

//move other elements
for ( Element = indexFrom ; Element != indexTo ; Element += magicIncrement )
    {
        targetArray [Element] = Array [Element + magicIncrement];
    }


//place target element to new position
targetArray [indexTo] = targetElement;



C/C++ example.

void magicFunction (arrayElementType targetArray[], int indexFrom, int indexTo){

    arrayElementType targetElement;
    int Element, magicIncrement;

    targetElement = targetArray[indexFrom];
    magicIncrement = (indexTo - indexFrom) / abs (indexTo - indexFrom);

    for (Element = indexFrom; Element != indexTo; Element += magicIncrement){
        targetArray[Element] = targetArray[Element + magicIncrement];
    }

    targetArray[indexTo] = targetElement;

}//end of function



ActionScript 3.0 example.

function magicFunction (targetArray[]:Array, indexFrom:int, indexTo:int):void {

    var targetElement = targetArray[indexFrom];
    var magicIncrement:int = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom);

    for (var Element:int = indexFrom; Element != indexTo; Element += magicIncrement){
        targetArray[Element] = targetArray[Element + magicIncrement];
    }

    targetArray[indexTo] = targetElement;

}//end of function



PHP example.

function magicFunction ($targetArray, $indexFrom, $indexTo) {

    $targetElement = $targetArray[$indexFrom];
    $magicIncrement = ($indexTo - $indexFrom) / abs ($indexTo - $indexFrom);

    for ($Element = $indexFrom; $Element != $indexTo; $Element += $magicIncrement){
        $targetArray[$Element] = $targetArray[$Element + $magicIncrement];
    }

    $targetArray[$indexTo] = $targetElement;

}//end of function



JavaScript example.

function magicFunction (targetArray, indexFrom, indexTo) {

    targetElement = targetArray[indexFrom];
    magicIncrement = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom);

    for (Element = indexFrom; Element != indexTo; Element += magicIncrement){
        targetArray[Element] = targetArray[Element + magicIncrement];
    }

    targetArray[indexTo] = targetElement;

}//end of function