Random range where key != value

Hi folks,

I’m trying to create a random numeric array where the keys don’t equal the values.

I’ve come up with this - it’s close but sometimes the last key equals it’s value.

Anyone got any other suggestions?

function random_range($min, $max)
{
	$n = range($min, $max);
	
	if(is_array($n))
	{
		shuffle($n);
		for($i=$min; $i<=$max; $i++)
		{
			if($i != $n[0])
			{
				$x[] = array_shift($n);
			}
			else
			{
				$x[] = array_pop($n);
			}
		}
		return $x;
	}
	return false;
}

Sounds like you’re trying to do a simple replacement cypher.


function random_range($min,$max) {
   $out = array();
   foreach(range($min,$max) as $i) {
      $done = false;
      while(!$done) {
        $rand = rand($min,$max);
        if(!isset($out[$rand]) && $i != $rand) {
          $out[$rand] = $i;
          $done = true;
        }
     }
   }
   return $out; 
}

Guys, thanks for your comments and help.

StarLion, That last snippet seems to work best. :tup: I knew I was nearly there, but just couldn’t quite crack it - thanks again…

Forgive me for being dumb, but why do you need the keys to be different from the values?

@StarLion Thanks, but it looks like it’s going to be too slow.

@Salathe It’s for a match game where two lists need to be sorted. When the game starts the list on the left must be different to the one on the right. You can see a demo here:
http://dev.dezertdezine.com/match-game-sortable.html

I still don’t see why they need to be different. You’re only making the game easier by adding that requirement.

Man does have a point. Enough playing and someone will notice that the answers NEVER are exactly across from each other.

Should be slightly faster this way, if less random.


  function random_range($min,$max) {
   $out = array();
   foreach(range($min,$max) as $i) {
      $done = false;
      $rand = rand($min,$max);
      while(!$done) {
        if(!isset($out[$rand]) && $i != $rand) {
          $out[$rand] = $i;
          $done = true;
        } else {
          $rand++;
          if($rand > $max) { $rand = $min; }
       }
     } 
   }
   return $out; 
}

That said, there was only one problem with your initial script, why not run a simple check at the end?


if ($x[(count($x)-1)] == $max) { //If the last value of the array = max
  $rand = rand(0,count($x) - 2); //Choose a random value somewhere else in the array.
  $x[(count($x)-1)] = $x[$rand]; //Put that value at the end of the array.
  $x[$rand] = $max; //Put the max value in the place you just chose.
}

Because at that point you know that everything else is random and NOT the max, therefore you can put any other value there.