Generate distinct random numbers using procedural code - php

I have been trying to generate distinct random numbers using procedural code. But i am failing to do it. Please help me in this regard. thanks in advance.
<?php
$rnd_array = array(0,0,0,0,0,0,0,0,0,0);
$a = 1;
for ($i=0; $a <= 10 ; $i++)
{
echo $rnd = rand() % 10;
echo "\t \t";
for ($j=0; $j < 10 ; $j++)
{
if ($rnd == $rnd_array[$j])
{
$flag = true;
break;
}
else
{
$flag = false;
}
}
if ($flag == false)
{
$rnd_array[$a] = $rnd;
$a++;
}
}
echo "<br> <br>";
for ($k=0; $k < 10 ; $k++)
{
echo $rnd_array[$k];
echo "\t \t";
}
?>

I would use a somewhat different logic - start with an empty array, generate a random number, put it into the array if the array doesn't already contain it. Repeat until your array contains as many elements as you want it to.
Here's a simple example:
$num = 10;
$min = 1;
$max = 100;
$array = [];
while (count($array) < $num) {
$random = mt_rand($min, $max);
if (!in_array($random, $array)) {
$array[] = $random;
}
}

10 distincts random numbers
<?php
$numbers = array();
$i = 0;
while($i < 10){
$new = rand();
$known = false;
foreach($numbers as $key => $value){
if($value == $new ){
$known = true;
break;
}
}
if(!$known){
$numbers[$i]=$new;
$i++;
}
}
var_dump($numbers);
?>

Because array length is equal to range of generated random value
$rnd_array = range(0,9);
shuffle($rnd_array);
print_r($rnd_array);
Array
(
[0] => 9
[1] => 0
[2] => 5
[3] => 3
[4] => 6
[5] => 4
[6] => 2
[7] => 7
[8] => 1
[9] => 8
)

Related

Generate non consecutive random numbers within a range

I have the following code
<?php
function randomGen($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
$tmp = array_slice($numbers, 0, $quantity);
//sort($tmp);
return $tmp;
}
echo '<pre>';
$arr = randomGen(2,7,5);
//sort($arr);}
print_r($arr);
This code generates random n numbers between the specified range.
However, it returns the output similar to the following many times
Array
(
[0] => 3
[1] => 4
[2] => 7
[3] => 5
[4] => 2
)
Here, 2 3 4 5 are consecutive numbers. I am trying to modify the above code so that it does not return more than 3 consecutive numbers. The output should be similar to this
Array
(
[0] => 2
[1] => 3
[2] => 5
[3] => 6
[4] => 7
)
As you can see, it has just 3 consecutive numbers 5 6 7.
I have tried the following
<?php
function randomGen($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
$tmp = array_slice($numbers, 0, $quantity);
sort($tmp);
return $tmp;
}
echo '<pre>';
$arr = randomGen(2,7,5);
$count = 0;
$first = $arr[0];
$i = 1;
//for($i = 1; $i < count($arr); $i++) {
while ($i < count($arr)) {
$ele = $arr[$i];
if ($counter >=3) {
$counter = 0;
$arr = randomGen(2,7,5);
$first = $arr[0];
$i = 1;
}
else {
if ($ele - $first === 1) {
$counter++;
//continue;
}
$first = $ele;
}
$i++;
}
print_r($arr);
But it doesn't provide the expected output.
Thanks in advance for any help.
Please see if we can do something like this
function randomGen($min, $max, $quantity,$rangestep) {
$numbers = range($min, $max,$rangestep);
$tmp = array_slice($numbers, 0, $quantity);
sort($tmp);
shuffle($tmp);
return $tmp;
}
echo '<pre>';
$arr = randomGen(2,7,5,1);
$count = 0;
$first = $arr[0];
$i = 1;
//for($i = 1; $i < count($arr); $i++) {
$counter = 0;
while ($i < count($arr)) {
$ele = $arr[$i];
if ($counter >=3) {
$counter = 0;
$arr = randomGen(2,7,8,2);
$first = $arr[0];
$i = 1;
}
else {
if ($ele - $first === 1) {
$counter++;
//continue;
}
$first = $ele;
}
$i++;
}
print_r($arr);
die;

PHP Shouldnot Repeat and should be from an array

I'm trying to build a script that does two thing.
1) The Numbers should not repeat.
2) The numbers should be from an array called $id.
<?php
$a = array(); // final array which will have our id's to display
$id = array(1, 3, 5, 7, 9); //final array should contain a number only from this list
$itemstoshow = 3; // how many items to display
for($i = 0; $i < $itemstoshow; $i++) {
do {
$a[$i] = assignid(9);
$chkid = checkeer($a[$i], $i);
$chkdata = chkdata($a[$i], $i);
} while($chkdata == "nonexist" or $chkid == "repeatedid");
}
// display numbers in the array
for($i = 0; $i < $itemstoshow; $i++) {
echo "Item " . $a[$i] . "--------";
}
// check for redundancy function
function checkeer($x, $y)
{ //first parameter is query aray second is counter
global $a;
$err = 0;
// check if repeating number
for($i = 0; $i <= $y - 1; $i++) {
if($x == $a[$i]) {
$err = 1;
}
}
if($err == 1) {
return "repeatedid";
}
}
//check if array $a holds value from $id or not
function chkdata($x, $y)
{
global $a;
global $id;
for($i = 0; $i <= $y - 1; $i++) {
if($x !== $id[$i]) {
return "nonexist";
}
}
}
//assign id function
function assignid($x)
{
return rand(1, $x);
}
problem number 1 solved problem number 2 still not solved please help me.
the code should show 3 numbers from 1 to 9 which donot repeat and are in the array $id
You could use a combination of array_rand and array_map to get random values from the array that has the values your basing the randomization. Take a look:
$id = array(1,3,5,7,9); //final array should contain a number only from this list
$itemstoshow = 3;
$values = array_map(function($item) use($id){
return $id[$item];
}, array_rand($id, $itemstoshow));
print_r($values);
Output:
Array
(
[0] => 1
[1] => 3
[2] => 9
)
Running again:
Array
(
[0] => 3
[1] => 7
[2] => 9
)
You can use array_rand that selects random keys:
$id = array(1,3,5,7,9);
$result = array_intersect_key($id, array_flip(array_rand($id, 3)));
Or you can shuffle the array and take for example the 3 first items:
$id = array(1,3,5,7,9);
$temp = $id;
shuffle($temp);
for ($i = 0; $i < 3; $i++) {
$result[] = $temp[$i];
}

Identify repeating pattern using PHP

I need to find the number of records that are greater than a specific float and find the group of data that repeat the most. For example, I have the data below and I need to find how many entries have values > 4.
1.5
1.7
4.5
4.7
4.8
1.4
4.5
4.9
In the above data the longest continuous repetition of values greater than 4 is 4.5,4.7,4.8. Therefore the total I would like returned should be 3. As you can see the pattern breaks after 4.8 since the number is 1.4 above. Is there a way to identify this pattern?
Try this, I have used here an array:
$arr = array(
0 => '1.5',
1 => '1.7',
2 => '4.5',
3 => '4.7',
4 => '4.8',
5 => '1.4',
6 => '4.5',
7 => '4.9'
);
$chk_val = 4; // value which is checking
$cnt = 0;$inc = 0;
foreach ($arr as $i => $val) {
if ($val > $chk_val) {
$inc++;
if ($inc > $cnt) { $cnt = $inc;}
} else {
$inc = 0;
}
}
echo $cnt;
try this
$n = 4; // number to check
$count = 0;
$max = 0;
$ele = array(1.5, 1.7, 4.5, 4.7, 4.8, 1.4, 4.5, 4.9);
for ($i = 0; $i < count($ele); $i++) {
if ($ele[$i] >= $n) { // check for greater element than given number
$count++; // increase consecutive counter variable
$arr[$max] = $count; //save continues max counter to array
} else {
$count = 0; //reset consecutive counter
$max++;
}
}
echo max($arr);
Quick and dirty...
function findNums($nums, $min = 4) {
$groups = array();
$groupcounts = array();
$groupindex = 0;
foreach($nums as $num) {
if($num > $min) {
$groups[$groupindex][] = $num;
if(array_key_exists($groupindex, $groupcounts)) {
$groupcounts[$groupindex]++;
} else {
$groupcounts[$groupindex] = 1;
}
} else {
$groupindex++;
}
}
return array($groupcounts, $groups);
}
// $your_numbers is your list
$nums = array_map('trim', explode("\n", $your_numbers));
$result = findNums($nums);
$counts = $result[0];
$maxcount = max($counts);
$groups = $result[1];
echo "max count is ".$maxcount." with values:\n";
$key = array_search($maxcount, $counts);
var_dump($groups[$key]);

Functions about random numbers

How can I create functions that answer to:
How many different numbers were generated during simulation?
% Of appearance of the numbers from 0 to 50 ?
What is the number that appeared several times during the simulation?
function randomDigits($numDigits) {
$arrayRange = 1000;
if ($numDigits <= 0) {
return '';
} else{
for($i=0; $i<$arrayRange; $i++){
echo mt_rand(0, 50) ." ";
}
}
}
$maxq = 100;
for ($i = 1; $i <= $maxq; $i++) {
echo $i . "<br>\n";
randomDigits($i) . "<br>\n----<br>\n";
}
If you store all the generated numbers into an array, you could use array_count_values()
This will count the occurrences of multiple key values in your array (e.g. if there are 12 occurrences of the number 7) and return the result in an array. This will only work for strings and integer values.
<?php
$array = ['a', 'a', 'a', 'a', 'b', 'b', 'c'];
print_r(array_count_values($array));
?>
Results from the above:
Array(
[a] => 4
[b] => 2
[c] => 1
)
From there, you should be able to easily do all the methods and outputs that you wish.
Here is the basic integration with your existing code...
<?php
$maxq = 100;
$returned_array = [];
for ($i = 1; $i <= $maxq; $i++) {
$returned_array = randomDigits($i); // return the generated array
// merge 'add' the two arrays, like saying i = i +2 or
// merged_array = merged_array + array
array_merge($returned_array, $returned_array);
// here you now have one array of 1000 random values
// print_r($returned_array);
// lets do some math
print_r(array_count_values($returned_array));
// this will show how many values were duplicates...
// e.g
// Array (
// [43] => 25 the number 43 was generated 25 times
// [25] => 22 the number 25 was generated 22 times
// [1] => 28 ect...
// you can loop through this array here and see which value was generated several times,
// format the results nicely, and do all sorts of maths on it as you wish
}
function randomDigits($numDigits) {
$arrayRange = 1000;
$generated_array = []; // here is an actual array that will store the generated numbers
if ($numDigits <= 0) {
return null;
} else {
for($i = 0; $i < $arrayRange; $i++) {
$random = mt_rand(0, 50);
array_push($generated_array, $random); // add the random value to the array
}
// here you have your array of generated numbers
return $generated_array;
}
}
?>
Example here - http://codepad.org/9Dv1CwR7
Sequence generation contains random integers for given length
function generate_array($count, $min, $max) {
$arr = array();
for ($i=0; $i<$count; $i++) {
$arr[$i] = rand($min, $max);
}
return $arr;
}
Calculating percentage of given interval (with a helper function):
function cnt($element, $arr){
$cnt = array_count_values($arr);
return $cnt[$element];
}
function percentages($min, $max, $arr) {
$total = sizeof($arr);
$occurences = 0;
while ($min < $max) {
if (!array_key_exists($min, $arr)) {
continue;
} else {
$occurences = $occurences + cnt($min, $arr);
}
$min++;
}
return $occurences/$total;
}
Add all simulated values to an array, and use array_count_values to get all unique values.
function randomDigits($numDigits) {
$arrayRange = 1000;
if ($numDigits <= 0) {
return '';
} else{
$arr=array();
for($i=0; $i<$arrayRange; $i++){
$val=mt_rand(0, 50);
$arr[]=$val;
echo $val ." ";
}
echo "\n";
$arr=array_count_values($arr);
echo "Total Unique numbers:".count($arr);
}
}
$maxq = 100;
for ($i = 1; $i <= $maxq; $i++) {
randomDigits($i) . "<br>\n----<br>\n";
}

Split a number into 4 specified parts thats togetter the same number [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Need to split a number for example 5000 into 4 parts in a array
$total = 5000;
Array should look like:
Array
(
[0] => 500
[1] => 250
[2] => 250
[3] => 4000
)
So if the user enters 600 for example i need a array like this:
Array
(
[0] => 500
[1] => 100
[2] => 0
[3] => 0
)
this is what i got, but im sure there is a better way. When i enter 600 for example i get 2 undefined offsets
$total_spidex = 5000;
$price_total = array();
for($i=1; $i<=$total_spidex; $i++)
{
if($i <= 500)
{
$price_total[1][] = $i;
}
elseif($i >500 && $i <= 750)
{
$price_total[2][] = $i;
}
elseif($i >750 && $i <= 1000)
{
$price_total[3][] = $i;
}
elseif($i >1000)
{
$price_total[4][] = $i;
}
}
$sum = 0;
$sum = (count($price_total[1]) * 12) + (count($price_total[2]) * 11) + (count($price_total[3]) * 10) + (count($price_total[4]) * 9);
$number = 5000; // initial number
$limit = 1000; // limit for chunks
$parts = array(
array(500, 250, 250, 0), // dividers for $number >= $limit, 0 - the rest of #
array(500, 250, 100, 0) // dividers for $number < $limit
);
$result = array(); // array with results
$blocks = $number < $limit; // which set of dividers to use
foreach($parts[$blocks] as $divider)
if ($number > $divider && $divider > 0) {
$result[] = $divider; // if number is larger than divider, add divider
$number -= $divider; // subtract divider from number
}
else {
$result[] = $number; // otherwise add the number
$number = 0; // and set it to zero
}
var_dump($result); // output result
No nested loops, extra conditions and you can easily modify and add more numerical values into $parts array. If there is no difference between the parts above and below the $limit, the code will be even more simple (may be I did not understand you correctly from comments)
$number = 500;
$parts = array(500, 250, 250, 0);
$result = array();
foreach($parts as $divider)
if ($number > $divider && $divider > 0) {
$result[] = $divider;
$number -= $divider;
}
else
{
$result[] = $number;
$number = 0;
}
var_dump($result);
Output is exactly what you asked for.
There you go, should be expresive by itself
<?php
function splitNumber($number)
{
if ($number >= 1000)
{
$t[0] = 500;
$t[1] = $t[2] = 250;
$t[3] = $number - ($t[0]+$t[1]+$t[2]);
}
else if ($number > 750 && $number < 1000)
{
$t[0] = 500;
$t[1] = 250;
$t[2] = $number - ($t[0]+$t[1]);
$t[3] = 0;
}
else
{
$t[0] = $number;
$t[1] = $t[2] = $t[3] = 0;
}
return $t;
}
// Some results
$my_number = splitNumber(768);
// Array ( [0] => 500 [1] => 250 [2] => 18 [3] => 0 )
$my_number = splitNumber(1953);
// Array ( [0] => 500 [2] => 250 [1] => 250 [3] => 953 )
$my_number = splitNumber(821);
// Array ( [0] => 500 [1] => 250 [2] => 71 [3] => 0 )
$my_number = splitNumber(2546);
// Array ( [0] => 500 [2] => 250 [1] => 250 [3] => 1546 )
// and so on ...
?>
Hope this helps.
An easy way...
$total_spidex = 5000;
$price_total = array();
$count = $total_spidex;
if ($count > 500){
$count -= 500;
$price_total[0] = 500;
if ($count > 250){
$count -= 250;
$price_total[1] = 250;
if ($count > 250){
$count -= 250;
$price_total[2] = 250;
if ($count > 750){
$count -= 750;
$price_total[3] = 750;
$price_total[4] = $count;
}
else $price_total[3] = $count;
}
else $price_total[2] = $count;
}
else $price_total[1] = $count;
}
else $price_total[0] = $count;
<?php
// your code goes here
$answer = array();
$value = 600;
if($value > 500){
array_push($answer, 500);
$value = $value-500;
}
else {
array_push($answer, $value);
$value = 0;
}
for ($i = 0; $i<2; $i++){
if ($value >250){
array_push($answer, 250);
$value = $value - 250;
}
else {
array_push($answer, $value);
$value = 0;
}
}
array_push($answer, $value);
print_r($answer);
?>
Here you go, based on your comments, this is I wrote.

Categories