PHP Using rand to pick between specific numbers - php

I know that rand(1,10); would generate a random number between 1 and 30.
How would I go about writing code that would pick a random number out of a group of numbers say 1,7,8 and 9?
Is it possible?
I am pretty sure rand is set up to only generate numbers within a range?

First thing is that rand(1,10) will generate a number between1 to 10 not 1 to 30.
PHP RAND FUNCTION
From a group of numbers, you can generate like this
$numbers = [1,7,8,9];
echo $numbers[rand(0,3)]

You can create custom array which you required, shuffle and get first value
$temp = [1,7,8,9];
shuffle($temp);
echo $temp[0];
shuffle — Shuffle an array
Demo

You could put your group of numbers into an array, and then use array_rand or shuffle to select one of them. For example:
$nums = array(1, 7, 8, 9);
$key = array_rand($nums);
echo $nums[$key] . PHP_EOL;
shuffle($nums);
echo $nums[0] . PHP_EOL;
Demo on 3v4l.org

Use this function (or inline code)
function SelectElementByRandom ( $list )
{
return count($list) ? $list[ rand(0,count($list)-1) ] : NULL;
}
The ?: operator ensures an result (NULL), even if the list is empty.
And for your example:
$result = SelectElementByRandom(array(1,7,8,9));

I would approach it like this. Create a loop that fills an array with random numbers in the range you're looking for (your group of numbers). After that, you choose a random index in that array, which is a random number in your group of numbers.
$min = 0;
$max = 10;
$group_size = 5;
$rand_group = array();
for($i = 0; $i < $group_size; $i++) {
$rand_group[$i] = rand($min,$max);
}
echo $rand_group[rand($min,$max)];

Related

Making an array with random repeated values within a range?

I'm making a small function in PHP that, like described in the title, need an array filled with random numbers inside a specified range, the numbers MUST repeat within it. As an example, filling an array with 20 random numbers between 1 and 10 should result in something like this:
Array = [2,5,8,2,8,5,3,9,6,3,4,6,3,1,2,1,2,3,7,1]
This code creates an array ($arr = array();) and then 20 times (the loop) pushes a random value on the end of the array.
The values are generated by random_int function that generates numbers in the given range (inclusively).
<?php
$arr = array();
for ($i = 0; $i < 20; $i++) {
array_push($arr, random_int(1, 10));
}
The source of randomness is quite good (depending on the system).
If you want such random number array generator as a function, do this:
<?php
function random_ints($count, $min, $max) {
$arr = array();
for ($i = 0; $i < $count; $i++) {
array_push($arr, random_int($min, $max));
}
}

Php variable random definite value

I try to create a variable who send a random value !
$random = mt_rand(5,10);
but i want the variable random with the number i choose like this:
$random = 5;10;15;20;25;30
The variable must send randomly 5 or 10 or 15 or 25 or 30 only
What you could do is using the mt_rand function with values from 1 to 6 then multiply them by 5.
Example:
$random = mt_rand(1, 6) * 5;
Like that?
$random = mt_rand(1,6) * 5;
Use array_rand to pick random key from array then you can put it into an another.
http://php.net/manual/en/function.array-rand.php
$input = array(5,10,15,20,25);
$rand_key = array_rand($input);
$another_array[] = $input[$rand_key];
You could use and array of element and get a random item
$items = Array(5,10,15,20,...50);
$myvalue = array_rand($items);
Assuming that you already have the values you want inside an array you can simply get a random position of the array. A rand() limited by the first element to the size of the array can solve this
<?php
$valores = [1,5,12,17,22,30,90,2,4,6]; // choose de values here
for($i=0;$i<200;$i++){ // just to print more than 1 value
echo $valores[rand(1,sizeof($valores))-1]."<br>"; // really pick the values here. start in 1 because we'll remove 1
}
Will it always be steps of 5? Then you could do something like
$random = mt_rand(1,6) * 5;
Otherwise I'd put the numbers that you want to choose from in an array and select a random element using mt_rand():
$random_temp = array(3,6,8,13,16,19);
$random = $random_temp[mt_rand(0,6)];
If the random numbers arrayed, then this may help:
$list=array(5,10,15,20,25,30);
$n=count($list)-1;
$random=$list(rand(0,$n));
$values = [5,10,15,20,25,30];
//shuffle the array
shuffle($values);
foreach($values as $v){
print $v;
}
always in different order...
You can use rand():
$random = rand(1, 6) * 5;
Will produce:
5, 10, 15, 25 or 30 randomly.
Please try this code
$random = rand(0,30);
if(($random%5)==0)
{
echo $random;
}
else
{
echo roundUpToAny($random);
}
function roundUpToAny($n,$x=5) {
return round(($n+$x/2)/$x)*$x;
}

Efficiently pick n random elements from PHP array (without shuffle)

I have the following code to pick $n elements from an array $array in PHP:
shuffle($array);
$result = array_splice($array, 0, $n);
Given a large array but only a few elements (for example 5 out of 10000), this is relatively slow, so I would like to optimize it such that not all elements have to be shuffled. The values must be unique.
I'm looking fo the most performant alternative. We can assume that $array has no duplicates and is 0-indexed.
$randomArray = [];
while (count($randomArray) < 5) {
$randomKey = mt_rand(0, count($array)-1);
$randomArray[$randomKey] = $array[$randomKey];
}
This will provide exactly 5 elements with no duplicates and very quickly. The keys will be preserved.
Note: You'd have to make sure $array had 5 or more elements or add some sort of check to prevent an endless loop.
This function performs a shuffle on only $n elements where $n is the number of random elements you want to pick. It will also work on associative arrays and sparse arrays. $array is the array to work on and $n is the number of random elements to retrieve.
If we define the $max_index as count($array) - 1 - $iteration.
It works by generating a random number between 0 and $max_index. Picking the key at that index, and replacing its index with the value at $max_index so that it can never be picked again, as $max_index will be one less at the next iteration and unreachable.
In summary this is the Richard Durstenfeld's Fisher-Yates shuffle but operating only on $n elements instead of the entire array.
function rand_pluck($array, $n) {
$array_keys = array_keys($array);
$array_length = count($array_keys);
$max_index = $array_length -1;
$iterations = min($n, $array_length);
$random_array = array();
while($iterations--) {
$index = mt_rand(0, $max_index);
$value = $array_keys[$index];
$array_keys[$index] = $array_keys[$max_index];
array_push($random_array, $array[$value]);
$max_index--;
}
return $random_array;
}
The trick is to use a variation of shuffle or in other words a partial shuffle.
performance is not the only criterion, statistical efficiency, i.e unbiased sampling is as important (as the original shuffle solution is)
function random_pick( $a, $n )
{
$N = count($a);
$n = min($n, $N);
$picked = array_fill(0, $n, 0); $backup = array_fill(0, $n, 0);
// partially shuffle the array, and generate unbiased selection simultaneously
// this is a variation on fisher-yates-knuth shuffle
for ($i=0; $i<$n; $i++) // O(n) times
{
$selected = mt_rand( 0, --$N ); // unbiased sampling N * N-1 * N-2 * .. * N-n+1
$value = $a[ $selected ];
$a[ $selected ] = $a[ $N ];
$a[ $N ] = $value;
$backup[ $i ] = $selected;
$picked[ $i ] = $value;
}
// restore partially shuffled input array from backup
// optional step, if needed it can be ignored, e.g $a is passed by value, hence copied
for ($i=$n-1; $i>=0; $i--) // O(n) times
{
$selected = $backup[ $i ];
$value = $a[ $N ];
$a[ $N ] = $a[ $selected ];
$a[ $selected ] = $value;
$N++;
}
return $picked;
}
NOTE the algorithm is strictly O(n) in both time and space, produces unbiased selections (it is a partial unbiased shuffling) and produces output which is proper array with consecutive keys (not needing extra array_values etc..)
Use example:
$randomly_picked = random_pick($my_array, 5);
// or if an associative array is used
$randomly_picked_keys = random_pick(array_keys($my_array), 5);
$randomly_picked = array_intersect_key($my_array, array_flip($randomly_picked_keys));
For further variations and extensions of shuffling for PHP:
PHP - shuffle only part of an array
PHP shuffle with seed
How can I take n elements at random from a Perl array?
This will only show benifits for small n compared to an array shuffle, but you could
Choose a random index r n times, each time decreasing the limit by 1
Adjust for previously used indices
Take value
Store used index
Pseudocode
arr = []
used = []
for i = 0..n-1:
r = rand 0..len-i
d = 0
for j = 0..used.length-1:
if r >= used[j]:
d += 1
arr.append($array[r + d])
used.append(r)
return arr
You could generate n-times a random number with mt_rand() and then fill these values in a new array. To go against the case where the same index gets returned twice we use the actual returned index to fill the new array and check always if the index exists in the new array, if so we use while to loop through it as long as we get a duplicate index. At the end we use array_values() to get a 0-indexed array.
$count = count($array) - 1;
$new_array = array();
for($i = 0; $i < $n; $i++) {
$index = mt_rand(0, $count);
while(isset($new_array[$index])) {
$index = mt_rand(0, $count);
}
$new_array[$index] = $array[$index];
}
$new_array = array_values($new_array);
I wonder why everyone here make it so complicated?
Here's the fastest and simplest way:
$randomArray = array_rand(array_flip($array), $n);

How can I make an array of all lists length x of the numbers 0 and 1?

I need to create an array like this:
$array = array(array(1,1,1,0,0,0,1,1), array(1,1,1,1,0,0,1,0));
but with all combinations of 1 and 0.
I wish to do this automatically, so I was thinking a for loop would be the best idea.
In other words the inner arrays should be all combos like 0,0,0,0,0,0,0,0 then 0,0,0,0,0,0,0,1 then 0,0,0,0,0,0,1,0 then 0,0,0,0,0,0,1,1. for all combos.
I started like this:
$array = array();
for($i =0;$i<100; $i++){
$array[$i] = 0;
}
How do I get this to do what I am trying to do?
Use decbin to convert your counter to binary.
str_pad allows you to pad strings, in this case I'm 0-padding it to a length of 8 bits.
$array = array();
for($i =0;$i<100; $i++){
$array[$i] = str_pad(decbin($i), 8, "0", STR_PAD_LEFT);;
}
var_dump($array);
Demo
This will print out an array of all binary variations from 00000000 to 11111111 where each one is in it's own array of chars.
$array = array();
for ($i = 0; $i < 256;)
{
$array[] = str_split(sprintf('%08d', decbin($i++)));
}
print_r($array);
See example

alternatives to php in_array for large arrays for avoiding duplicates entries

I need to generate a large list of random numbers from 600k to 2000k, but the
list can not have duplicates.
My current 'implementation' looks like this:
<?php
header('Content-type: text/plain');
$startTime = microtime(true);
$used = array();
for ($i=0; $i < 600000; ) {
$random = mt_rand();
//if (!in_array($random, $used)) {
$used[] = $random;
$i++;
//}
}
$endTime = microtime(true);
$runningTime = $endTime - $startTime;
echo 'Running Time: ' . $runningTime;
//print_r($used);
?>
If I keep the in_array test commented the processing time is around 1 second, so
the mt_rand calls and the used array filling are relatively 'cheap' but when I uncomment
the in_array test bad things happens! (I'm just waiting -it's been more then 10 minutes- for the script to terminate...)
So I'm looking for alternatives either on the duplicate detection side or in the generation part (How could i generate random numbers without the risk of getting duplicates)
I'm open to any suggestion.
For a quick/dirty solution, does using/checking array keys improve your speed at all?
$used = array();
for ($i = 0; $i < 600000; ) {
$random = mt_rand();
if (!isset($used[$random])) {
$used[$random] = $random;
$i++;
}
}
$used = array_values($used);
in_array requires to search the whole array in the worst case, that means linear costs (O(n)). But using the array key as – well – the key, the costs are constant (O(1)) since the costs for array access is always constant.
You could for example do something like this instead
$random = mt_rand();
$array = range($random, $random + 600000);
$array = shuffle($array);
That would create a array that first is in order, but then it shuffles the array, so the values will be random. No collisions! :D
If you do the looping anyways and if you don't need more than 600000 why would you check them at all, why not just append $i to $random. done. not random enough?
for ($i = 0; $i < 600000; $i++)
{
$yourArray[] = mt_rand() . $i;
}
Furthermore there is the array function array_unique, which removes duplicate values from an array.

Categories