Tweeted twitter.com/#!/StackProgrammer/status/548693474024124416
2 Correction to logic so code example works for minVal != 0
source | link

Given an integer range and a number within that range, what's a reasonably robust and efficient way to randomly select a new number within the range such that it's not equal to the given number?

Whenever I need to do this, I usually use something like:

// Randomly choose an integer within an inclusive range with the condition
// that the result not equal the previous number chosen
// INPUT: lastNum is an int in the range [minVal, maxVal]
int ChooseNewNumber(lastNum){

    minVal = 0;
    maxVal = N; // This would usually be a value like someContainer.size - 1
    intervalLength = maxVal - minVal + 1;

    // Assume RandomInt...() is an existing function that lives up to its name
    int newNum = RandomIntWithinInclusiveRange(minVal, maxVal);

    if (newNum == lastNum){
        // Add a random offset to newNum and wrap around if necessary
        newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
    }

    return newNum;
}

This works and it seems to avoid the introduction of any bias in the newNum == lastNum case, but it's a bit clunky. Is there a cleaner way to accomplish the same thing?

EDIT: as coredump pointed out, the method above fails if minVal != 0. Just for reference, the line:

newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);

should be:

new = ((new + RandomIntWithinInclusiveRange(1, intervalLength - 1) - minVal) % intervalLength) + minVal;

I realize this mistake gave the impression that minVal might always be 0; sorry about that.

Given an integer range and a number within that range, what's a reasonably robust and efficient way to randomly select a new number within the range such that it's not equal to the given number?

Whenever I need to do this, I usually use something like:

// Randomly choose an integer within an inclusive range with the condition
// that the result not equal the previous number chosen
// INPUT: lastNum is an int in the range [minVal, maxVal]
int ChooseNewNumber(lastNum){

    minVal = 0;
    maxVal = N; // This would usually be a value like someContainer.size - 1
    intervalLength = maxVal - minVal + 1;

    // Assume RandomInt...() is an existing function that lives up to its name
    int newNum = RandomIntWithinInclusiveRange(minVal, maxVal);

    if (newNum == lastNum){
        // Add a random offset to newNum and wrap around if necessary
        newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
    }

    return newNum;
}

This works and it seems to avoid the introduction of any bias in the newNum == lastNum case, but it's a bit clunky. Is there a cleaner way to accomplish the same thing?

Given an integer range and a number within that range, what's a reasonably robust and efficient way to randomly select a new number within the range such that it's not equal to the given number?

Whenever I need to do this, I usually use something like:

// Randomly choose an integer within an inclusive range with the condition
// that the result not equal the previous number chosen
// INPUT: lastNum is an int in the range [minVal, maxVal]
int ChooseNewNumber(lastNum){

    minVal = 0;
    maxVal = N; // This would usually be a value like someContainer.size - 1
    intervalLength = maxVal - minVal + 1;

    // Assume RandomInt...() is an existing function that lives up to its name
    int newNum = RandomIntWithinInclusiveRange(minVal, maxVal);

    if (newNum == lastNum){
        // Add a random offset to newNum and wrap around if necessary
        newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
    }

    return newNum;
}

This works and it seems to avoid the introduction of any bias in the newNum == lastNum case, but it's a bit clunky. Is there a cleaner way to accomplish the same thing?

EDIT: as coredump pointed out, the method above fails if minVal != 0. Just for reference, the line:

newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);

should be:

new = ((new + RandomIntWithinInclusiveRange(1, intervalLength - 1) - minVal) % intervalLength) + minVal;

I realize this mistake gave the impression that minVal might always be 0; sorry about that.

1
source | link

Choosing a random integer in a range such that it doesn't equal a particular number

Given an integer range and a number within that range, what's a reasonably robust and efficient way to randomly select a new number within the range such that it's not equal to the given number?

Whenever I need to do this, I usually use something like:

// Randomly choose an integer within an inclusive range with the condition
// that the result not equal the previous number chosen
// INPUT: lastNum is an int in the range [minVal, maxVal]
int ChooseNewNumber(lastNum){

    minVal = 0;
    maxVal = N; // This would usually be a value like someContainer.size - 1
    intervalLength = maxVal - minVal + 1;

    // Assume RandomInt...() is an existing function that lives up to its name
    int newNum = RandomIntWithinInclusiveRange(minVal, maxVal);

    if (newNum == lastNum){
        // Add a random offset to newNum and wrap around if necessary
        newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
    }

    return newNum;
}

This works and it seems to avoid the introduction of any bias in the newNum == lastNum case, but it's a bit clunky. Is there a cleaner way to accomplish the same thing?