Random Number from an Array Without Repeating the Same Number Twice in a Row

Random number from an array without repeating the same number twice in a row?

The code below doesn't random the same number.

   var currentNo: UInt32 = 0

func randomNumber(maximum: UInt32) -> Int {

var randomNumber: UInt32

do {
randomNumber = (arc4random_uniform(maximum))
}while currentNo == randomNumber

currentNo = randomNumber

return Int(randomNumber)
}

math random number without repeating a previous number

There are a number of ways you could achieve this.

Solution A:
If the range of numbers isn't large (let's say less than 10), you could just keep track of the numbers you've already generated. Then if you generate a duplicate, discard it and generate another number.

Solution B:
Pre-generate the random numbers, store them into an array and then go through the array. You could accomplish this by taking the numbers 1,2,...,n and then shuffle them.

shuffle = function(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};

var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;

setInterval(function() {
$('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);

Solution C:
Keep track of the numbers available in an array. Randomly pick a number. Remove number from said array.

var randnums = [0,1,2,3,4,5,6];

setInterval(function() {
var m = Math.floor(Math.random()*randnums.length);
$('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
randnums = randnums.splice(m,1);
}, 300);

How to avoid generating the same random String twice in a row in Swift?

Since you only care about not repeating the value as the next value, just remember the previous value and reject the next value if it is the same as the previous value.

Here's a playground example. First, we try this the simplest way:

let pep = ["manny", "moe", "jack"]

func fetchRandomPep() -> String {
return pep.randomElement()!
}

for _ in 1...100 {
let result = fetchRandomPep()
print(result)
}

Well, you probably got many repeated results. Let's prevent that by writing our loop in a different way:

var prev = ""
for _ in 1...100 {
var result = fetchRandomPep()
while result == prev {
result = fetchRandomPep()
}
prev = result
print(result)
}

Now there are no repetitions!

How to generate a random number in Swift without repeating the previous random number?

Store the previous generated number in a variable and compare the generated number to the previous number. If they match generate a new random number. Repeat the generation of new numbers until they don't match.

var previousNumber: UInt32? // used in randomNumber() 

func randomNumber() -> UInt32 {
var randomNumber = arc4random_uniform(10)
while previousNumber == randomNumber {
randomNumber = arc4random_uniform(10)
}
previousNumber = randomNumber
return randomNumber
}

Create a random number array without having a number repeat twice in a row

This will work fine:

var imageString:String = self.imageArray[randomNumber(6)]

As you can see in your function declaration func randomNumber(maximum: UInt32) -> Int which means your function accept an argument maximum which is type of UInt32 and return Int.

But you are using your function like self.imageArray[randomNumber] where you want to access an element from imageArray with randomNumber function.

But your function accepts parameter which you doesn't assign so you can use your function this way randomNumber(6) where 6 is a max value.

And you can change your max value as per your need.

Creating random numbers with no duplicates

The simplest way would be to create a list of the possible numbers (1..20 or whatever) and then shuffle them with Collections.shuffle. Then just take however many elements you want. This is great if your range is equal to the number of elements you need in the end (e.g. for shuffling a deck of cards).

That doesn't work so well if you want (say) 10 random elements in the range 1..10,000 - you'd end up doing a lot of work unnecessarily. At that point, it's probably better to keep a set of values you've generated so far, and just keep generating numbers in a loop until the next one isn't already present:

if (max < numbersNeeded)
{
throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set<Integer> generated = new LinkedHashSet<Integer>();
while (generated.size() < numbersNeeded)
{
Integer next = rng.nextInt(max) + 1;
// As we're adding to a set, this will automatically do a containment check
generated.add(next);
}

Be careful with the set choice though - I've very deliberately used LinkedHashSet as it maintains insertion order, which we care about here.

Yet another option is to always make progress, by reducing the range each time and compensating for existing values. So for example, suppose you wanted 3 values in the range 0..9. On the first iteration you'd generate any number in the range 0..9 - let's say you generate a 4.

On the second iteration you'd then generate a number in the range 0..8. If the generated number is less than 4, you'd keep it as is... otherwise you add one to it. That gets you a result range of 0..9 without 4. Suppose we get 7 that way.

On the third iteration you'd generate a number in the range 0..7. If the generated number is less than 4, you'd keep it as is. If it's 4 or 5, you'd add one. If it's 6 or 7, you'd add two. That way the result range is 0..9 without 4 or 6.

How to generate random numbers from a list, without repeating the last one?

You could create a generator to generate them:

import random

def random_without_pairs(data):
values = set(data)
previous = None
while True:
new = random.sample(values, 1)[0]
yield new
values.remove(new)
if previous is not None:
values.add(previous)
previous = new

Note the use of random.sample(values, 1) to generate a list of one value from the set, as random.choice can only be used on sequences.

You can use it like this:

l = [0,1,2,3]
r = random_without_pairs(l) # create the generator that will generate values from l
for i in range(10):
print(next(r))

2
3
2
3
1
3
0
2
0
3

If you want to create a list of n random values without pairs from your list, you can use this little helper function:

def n_random_without_pairs(data, n):
r = random_without_pairs(data)
return [next(r) for _ in range(n)]

print(n_random_without_pairs(l, 10))

#[1, 3, 2, 3, 2, 3, 0, 1, 3, 1]


Related Topics



Leave a reply



Submit