I am implementing a brainfuck interpreter in Javascript. I am representing the memory with an array and I would like to have the option to limit the array indexes within a range. If the index is outside of this range, I want it to go over or under the limits. I'm having a little trouble describing the problem correctly. Here is an example of what I am thinking of:
lbound: 0, ubound: 10, index: 10, result: 0
lbound: 0, ubound: 10, index: 11, result: 1
lbound: -10, ubound: 0, index: -10, result: 0
lbound: -10, ubound: 0, index: -11, result: -1
lbound: -5, ubound: 15, index: 16, result: -4
lbound: 5, ubound: 15, index: 26, result: 6
I could make up a function something like:
if (index < lbound) {
// underflow
return ubound - index - index * Math.round(index / lbound)
}
if (index > ubound) {
// overflow
return lbound index - index * Math.round(index / ubound)
}
return index
But that's too naive and missis the case of dividing by zero. I guess I have a wrong approach here. Basically, I'm looking for a math formula that maps a specific number within a range including negative numbers. But not a simple reassignment. The correct number of overshoots or undershoots must be calculated. Therefore the whole parts of lbound or ubound have to be subtracted from index. And finally the difference hast to be added or subtracted to lbound or ubound.
Any help would be great. :)
CodePudding user response:
Basically modulo is the operation you're looking for. Just that you're making it a bit trickier, since you also want to support negative numbers, so a little bit of "rotating" the modulo result needs to be added to the "formula".
This function below should do the trick:
function keepIndexInsideRange(index, lbound, ubound) {
var range = Math.abs(ubound - lbound);
var result = index % range;
if (lbound < 0 && index > ubound) {
result = -(range - result);
}
return result;
}
console.log('should return 0', keepIndexInsideRange(10, 0, 10)); // OK
console.log('should return 1', keepIndexInsideRange(11, 0, 10)); // OK
console.log('should return 0', keepIndexInsideRange(-10, -10, 0)); // OK
console.log('should return -1', keepIndexInsideRange(-11, -10, 0)); // OK
console.log('should return -9', keepIndexInsideRange(1, -10, 0)); // OK
console.log('should return -4', keepIndexInsideRange(16, -5, 15)); // OK
console.log('should return 6', keepIndexInsideRange(26, 5, 15)); // OK
You can play with it here https://stackblitz.com/edit/typescript-lxw3ai?file=index.ts (just expand the console on the right hand side of the screen).