Given a circular array, what is an efficient way to determine the minimum distance between two elements?
For example moving from here
[0,0,0,0,0,1]
To here
[1,0,0,0,0,0]
Is more convenient from the outer bounds, whilst moving from here
[0,0,0,0,0,1]
to here
[0,0,0,1,0,0]
is more convenient internally.
My initial idea was this:
sourceLocation = rotatorElements["pos"].indexOf(1);
targetLocation = rotatorElements["pos"].rotate(delta).indexOf(1);
var D = Math.abs(targetLocation - sourceLocation);
var O = Math.abs(rotatorElements["pos"].length - D);
if ((D - O == 0)) direction = 1;
else {
if (D < O) direction = -1;
else direction = 1;
}
Note: rotate
rotates the circular array by a defined number of positions.
Calculating the absolute distance between the elements is useful:
var dist = Math.abs(targetLocation - sourceLocation);
Then you can just check if it's more or less than half the length of the array. If the distance is more than half the length, it's closer to wrap around:
if (dist < rotatorElements["pos"].length / 2) {
// move internally
} else {
// wrap around
}
I pasted the code together:
function move(sourceLocation, targetLocation, length) {
var dist = Math.abs(targetLocation - sourceLocation);
var direction = sourceLocation < targetLocation ? 1 : -1;
if (dist < length / 2) {
console.log('internally, direction =', direction);
} else {
console.log('wrap, direction =', -direction);
}
}
move(5, 0, 6);
move(5, 3, 6);
Output:
wrap, direction = 1
internally, direction = -1
Demo: http://jsfiddle.net/bUCmk/
Edit: I think I answered the question in the title, but what you want is a direction not a distance. Then:
function getDirection(from, to, array) {
if (from === to) {
return 0;
}
var internal = (Math.max(from, to) - Math.min(from, to) < array.length/2) ? true : false;
if (internal && from < to
||
!internal && from > to
) {
return 1;
} else {
return -1;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With