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

早过忘川 提交于 2019-12-02 09:55:27

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)
    }
Ian MacDonald

I think Larme's suggestion is pretty clever, actually.

easyArray.append(easyArray.removeAtIndex(Int(arc4random_uniform(UInt32(easyArray.count)-1))))
selector.runAction(SKAction.moveTo(easyArray.last!, duration: 0))

I would recommend to not use while() loops with randomizers.

Theoretically it can cause infinite loops in worst case scenario, in more positive scenario it will just take few loops before you get desired results.

Instead I would advice to make an NSArray of all values, remove from this NSArray last randomized element and randomize any of other existing elements from such an array - that is guarantee result after only one randomize iteration.

It can be easily achieved by making NSArray category in Objective-C:

- (id) randomARC4Element
{
    if(self.count > 0)
    {
        return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
    }

    return nil;
}

- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
    return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}

- (float)randomFloat
{
    return (float) arc4random() / UINT_MAX;
}
truest.wizzle

If you can use then you can select a random value that doesn't match the last value. Then for any left over values you can loop through and find valid places to insert them.

It's not the most efficient but it works.

public static List<int> Randomize(List<int> reps, int lastId) {
  var rand = new Random();

  var newReps = new List<int>();
  var tempReps = new List<int>();
  tempReps.AddRange(reps);
  while (tempReps.Any(x => x != lastId)) {
    var validReps = tempReps.FindAll(x => x != lastId);
    var i = rand.Next(0, validReps.Count - 1);
    newReps.Add(validReps[i]);
    lastId = validReps[i];
    tempReps.Remove(validReps[i]);
  }
  while (tempReps.Any()) {
    var tempRep = tempReps.First();
    bool placed = false;
    for (int i = 0; i < newReps.Count; i++) {
      if (newReps[i] == tempRep) {
        continue;
      }
      else if ((i < newReps.Count - 1) && (newReps[i + 1] == tempRep)) {
        continue;
      }
      else {
        newReps.Insert(i + 1, tempRep);
        placed = true;
        break;
      }
    }

    if (placed) {
      tempReps.Remove(tempRep);
    }
    else {
      throw new Exception("Unable to randomize reps");
    }
  }
  return newReps;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!