custom php random function - php

Any php random function which gives number of random numbers specified and with in the boundaries defined.
For example numbers from 1 to 5000
And I need 5 random numbers.
I know there is function which work for array indexes array_rand
I need similar for numbers and boundaries defines. At least the upper boundry defined.

Here I used mt_rand instead rand (much faster):
function randomNumbers($min, $max, $count = 1) {
$randomFunc = function () use ($min, $max) { return mt_rand($min, $max); };
return array_map($randomFunc, range(1, $count));
}

Why not make a function?
function randomArray($count, $min, $max){
$randomArray = array();
for ($i = 0; $i < $count; $i++) {
$randomArray[] = rand($min, $max);
}
return $randomArray;
}
Your case would be:
$randoms = randomArray(5, 1, 5000);

You can try this
<?php
function random_generator($digits)
{
srand((double) microtime() * 10000000);
//Array of alphabets or numeric ,you can define
$input = array ("0", "1", "2", "3","4");
$random_generator="";// Initialize the string to store random numbers
for($i=1;$i<$digits+1;$i++)
{ // Loop the number of times of required digits
if(rand(1,2) == 1){// to decide the digit should be numeric or alphabet
// Add one random alphabet
$rand_index = array_rand($input);
$random_generator .=$input[$rand_index]; // One char is added
}
else
{
// Add one numeric digit between 1 and 10
$random_generator .=rand(1,10); // one number is added
}
// end of if else
}
// end of for loop
return $random_generator;
}
echo random_generator(5);
?>

Will return unique random number, you have pass 3 value to function: Min, Max and Count (number of random value)
function rand5($min,$max,$count){
$num = array();
for($i=0 ;i<$count;i++){
if(!in_array(mt_rand($min,$max),$num)) {
$num[]=mt_rand($min,$max);
}
else {
$i--;
}
}
return $num;
}
Hope will help!

use of define may be alternative in PHP
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid red;
}
</style>
</head>
<body bgcolor="gold">
<table style="width:25%">
<?php
// code by Bhupinder Deol
define('MIN', 1);
define('MAX', 49);
define('ROWS', 10);
define('NUMS', 6);
for($y=0;$y <ROWS;$y++){ // for loop started for $y
for($x=0;$x<NUMS;$x++) {
$a[$x]=rand(MIN,MAX);
}
asort($a);
$a=array_unique($a);
if (count($a) == NUMS)
{
// print_r($a);
echo "<tr>";
foreach ($a as $value) {
echo "<td>$value</td>";
// echo $value." ";
}
echo "</tr>";
`enter code here` $x=0;
}
else
{
--$y;
$x=0;
}
} // for loop ended for $y
?>
</table>
<h1> Total lottery lines created = <?php echo ROWS." for ". NUMS. "/" .MAX; ?>

Related

do-while loop only runs once

I am trying to make a simple while loop using a class to get the factorial of a number. However, for some reason, the while loop is only returning the value after it has run once.
Here is my code:
<?php
class Factorial {
public function calculate($int){
$intStep = $int-1;
do {
$int*=$intStep;
$int--;
return $int;
} while($int>0);
if (!is_int($int)){
echo "entry is not a number";
}
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);
I see a number of problems with your code:
return $int; is run inside the do while loop, which means it'll only ever run once.
You're decrementing $int instead of $intStep
You're checking if $int is below zero instead of $intStep
Here's your code with all of these problems fixed, it works and returns 15:
class Factorial {
public function calculate ($int) {
if (!is_int($int)) {
echo "entry is not a number";
}
$intStep = $int - 1;
do {
$int += $intStep;
$intStep--;
} while ($intStep > 0);
return $int;
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);
3v4l.org demo
You shouldn't return from your function until your result is ready. Since you return early, you won't finish your calculation.
In general, your life will be easier if you learn how to debug. For PHP, the easiest way would be to echo stuff throughout your code. If you put echo $int inside of your loop it would be more obvious to you what the issue was.
try this
<?php
class Factorial {
public function calculate($num){
$Factorial = 1;
$i =1;
do{
$Factorial *= $i;
$i++;
}while($i<=$num);
return $Factorial;
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);
?>
Factorial ? Maybe the following code is what you want:
Don't forget negative Numbers.
class Factorial {
public function calculate ($int) {
if (!is_int($int)) {
echo "entry is not a number";
}
if ($int == 0 || $int == 1) {
$result = 1;
} else if ($int < 0) {
$result = $this->calculate($int + 1) * $int;
} else {
$result = $this->calculate($int - 1) * $int;
}
return $result;
}
}
$factorial = new Factorial;
echo $factorial->calculate(-4);

PHP find Exponent after remainder is zero

I have this code written but I am having little issue or might be I am missing something,
public function test()
{
$number = "8192";
for ($i=1; $i<=32; $i++)
{
if(($number % pow(2,$i)) == 0)
{
$final = 32-$i;
echo $final;
}
}
exit;
}
I need to get which Exponent aka $i is used and then need to minus the value from 32 (or something else) to get the final results.
Since you want to compare the values just change the if condition, the modulus operator will not give you the exact result,
Here is the complete answer :
public function test()
{
$number = "8192";
for ($i=1; $i<=32; $i++)
{
if($number == pow(2,$i))
{
$final = 32-$i;
echo $final;
break;
}
}
exit;
}

Rewrite a large number of for loops into something shorter

I have the following code:
for($a=1; $a<strlen($string); $a++){
for($b=1; $a+$b<strlen($string); $b++){
for($c=1; $a+$b+$c<strlen($string); $c++){
for($d=1; $a+$b+$c+$d<strlen($string); $d++){
$tempString = substr_replace($string, ".", $a, 0);
$tempString = substr_replace($tempString, ".", $a+$b+1, 0);
$tempString = substr_replace($tempString, ".", $a+$b+$c+2, 0);
$tempString = substr_replace($tempString, ".", $a+$b+$c+$d+3, 0);
echo $tempString."</br>";
}
}
}
}
What it does is to make all possible combinatons of a string with several dots.
Example:
t.est123
te.st123
tes.t123
...
test12.3
Then, I add one more dot:
t.e.st123
t.es.t123
...
test1.2.3
Doing the way I'm doing now, I need to create lots and lots of for loops, each for a determined number of dots. I don't know how I can turn that example into a functon or other easier way of doing this.
Your problem is a combination problem. Note: I'm not a math freak, I only researched this information because of interest.
http://en.wikipedia.org/wiki/Combination#Number_of_k-combinations
Also known as n choose k. The Binomial coefficient is a function which gives you the number of combinations.
A function I found here: Calculate value of n choose k
function choose($n, $k) {
if ($k == 0) {return 1;}
return($n * choose($n - 1, $k - 1)) / $k;
}
// 6 positions between characters (test123), 4 dots
echo choose(6, 4); // 15 combinations
To get all combinations you also have to choose between different algorithms.
Good post: https://stackoverflow.com/a/127856/1948627
UPDATE:
I found a site with an algorithm in different programming languages. (But not PHP)
I've converted it to PHP:
function bitprint($u){
$s= [];
for($n= 0;$u > 0;++$n, $u>>= 1) {
if(($u & 1) > 0) $s[] = $n;
}
return $s;
}
function bitcount($u){
for($n= 0;$u > 0;++$n, $u&= ($u - 1));
return $n;
}
function comb($c, $n){
$s= [];
for($u= 0;$u < 1 << $n;$u++) {
if(bitcount($u) == $c) $s[] = bitprint($u);
}
return $s;
}
echo '<pre>';
print_r(comb(4, 6));
It outputs an array with all combinations (positions between the chars).
The next step is to replace the string with the dots:
$string = 'test123';
$sign = '.';
$combs = comb(4, 6);
// get all combinations (Th3lmuu90)
/*
$combs = [];
for($i=0; $i<strlen($string); $i++){
$combs = array_merge($combs, comb($i, strlen($string)-1));
}
*/
foreach ($combs as $comb) {
$a = $string;
for ($i = count($comb) - 1; $i >= 0; $i--) {
$a = substr_replace($a, $sign, $comb[$i] + 1, 0);
}
echo $a.'<br>';
}
// output:
t.e.s.t.123
t.e.s.t1.23
t.e.st.1.23
t.es.t.1.23
te.s.t.1.23
t.e.s.t12.3
t.e.st.12.3
t.es.t.12.3
te.s.t.12.3
t.e.st1.2.3
t.es.t1.2.3
te.s.t1.2.3
t.est.1.2.3
te.st.1.2.3
tes.t.1.2.3
This is quite an unusual question, but I can't help but try to wrap around what you are tying to do. My guess is that you want to see how many combinations of a string there are with a dot moving between characters, finally coming to rest right before the last character.
My understanding is you want a count and a printout of string similar to what you see here:
t.est
te.st
tes.t
t.es.t
te.s.t
t.e.s.t
count: 6
To facilitate this functionality I came up with a class, this way you could port it to other parts of code and it can handle multiple strings. The caveat here is the strings must be at least two characters and not contain a period. Here is the code for the class:
class DotCombos
{
public $combos;
private function combos($string)
{
$rebuilt = "";
$characters = str_split($string);
foreach($characters as $index => $char) {
if($index == 0 || $index == count($characters)) {
continue;
} else if(isset($characters[$index]) && $characters[$index] == ".") {
break;
} else {
$rebuilt = substr($string, 0, $index) . "." . substr($string, $index);
print("$rebuilt\n");
$this->combos++;
}
}
return $rebuilt;
}
public function allCombos($string)
{
if(strlen($string) < 2) {
return null;
}
$this->combos = 0;
for($i = 0; $i < count(str_split($string)) - 1; $i++) {
$string = $this->combos($string);
}
}
}
To make use of the class you would do this:
$combos = new DotCombos();
$combos->allCombos("test123");
print("Count: $combos->combos");
The output would be:
t.est123
te.st123
tes.t123
test.123
test1.23
test12.3
t.est12.3
te.st12.3
tes.t12.3
test.12.3
test1.2.3
t.est1.2.3
te.st1.2.3
tes.t1.2.3
test.1.2.3
t.est.1.2.3
te.st.1.2.3
tes.t.1.2.3
t.es.t.1.2.3
te.s.t.1.2.3
t.e.s.t.1.2.3
Count: 21
Hope that is what you are looking for (or at least helps)....

How can I remove last digit from decimal number in PHP

I want to remove last digit from decimal number in PHP.
Lets say I have 14.153. I want it to be 14.15. I will do this step till my number is no longer decimal.
I think this should work:
<?php
$num = 14.153;
$strnum = (string)$num;
$parts = explode('.', $num);
// $parts[0] = 14;
// $parts[1] = 153;
$decimalPoints = strlen($parts[1]);
// $decimalPoints = 3
if($decimalPoints > 0)
{
for($i=0 ; $i<=$decimalPoints ; $i++)
{
// substring($strnum, 0, 0); causes an empty result so we want to avoid it
if($i > 0)
{
echo substr($strnum, 0, '-'.$i).'<br>';
}
else
{
echo $strnum.'<br>';
}
}
}
?>
echo round(14.153, 2); // 14.15
The round second parameter sets the number of digits.
You can try this.
Live DEMO
<?php
$number = 14.153;
echo number_format($number,2);

Set condition in wordsearch so letters of words will not intersect with each other?

I'm trying to make a wordsearch game using php. First I will create the table/grid and then populate the table with random letters and then I will replace the random letters with the letters of the words as well as determining the direction of the words either HORIZONTAL, VERTICAL or DIAGONAL. The problem is, the letters of words intersect with each other, which messed up the table. The questions are,
How to set condition where in letters of words will not intersect with each other
How to determine if the current position is already occupied by the other words letter?
I'm having problem with the letters of words they keep intersecting with each other.
Any idea?
$row = 5;
$col = 5;
$characters = range('a','z');
$max = count($characters) - 1;
$rc = array();
for ($r=1;$r<=$row;$r++)
{
for ($c=1;$c<=$col;$c++)
{
$rc['r'.$r.'c'.$c] = $characters[mt_rand(0,$max)];
$fill['r'.$r.'c'.$c] = '';
}
}
$directions = array('H', 'V', 'D');
$wrdList =array('four', 'data', 'howl');
foreach ($wrdList as $wrd)
{
$wrdLen = strlen($wrd);
$dir = $directions[mt_rand(0,2)];
if ($dir =="H" or $dir=="D" )
{
$limitRow = $row - $wrdLen+1;
$limitCol = $col - $wrdLen+1;
$startPointRow = 1;
$startPointCol = 1;
}
elseif ($dir=="V")
{
$limitRow = $row - $wrdLen + 1;
$limitCol = $col;
$startPointRow = 1;
$startPointCol = 1;
}
$temprow = mt_rand($startPointRow,$limitRow);
$tempcol = mt_rand($startPointCol,$limitCol);
while($wrdLen >0)
{
$thisChar= substr($wrd,0,1);
$wrd = substr($wrd,1);
$wrdLen--;
$x = 'r'.$temprow.'c'.$tempcol;
$rc[$x] = $thisChar;
$fill[$x] = '#2952f8';
if($dir=="D")
{
$tempcol++;
$temprow++;
}
elseif($dir=="V")
{
$temprow++;
}
elseif($dir=="H")
{
$tempcol++;
}
}
}
#--Display the random letters and the words
echo '<table style="border:1px solid #000">';
for ($r=1;$r<=$row;$r++)
{
echo '<tr style="border:1px solid #000">';
for ($c=1;$c<=$col;$c++)
{
$thisChar=$rc['r'.$r.'c'.$c];
$fills = $fill['r'.$r.'c'.$c];
echo '<td style="border:1px solid #000; background-color: '.$fills.'">';
echo $thisChar;
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
You're doing it backwards. First put in the words you want, then put in the random letters.
Before you put in each successive word, choose the random path for that word, and then along that path, check that there aren't any non-matching letters. (E.g. if 'alphabet' crosses the word 'graph' in a place where they both have a letter 'a', it's okay; otherwise, find a different spot for 'alphabet'). Finally, after all the words are in place, go through the whole thing and put random letters in the spots that don't have letters. Or, if you can't find a place for all the words, start over again.
EDIT:
How to find letters in particular spots. Okay. So, taking a look at your code, you are doing something illogical here:
$rc['r'.$r.'c'.$c] = $characters[mt_rand(0,$max)];
You are creating a one-dimensional array out of, essentially, the product of two keys. Instead, you want to do a two-dimensional array. This makes complete sense because a) you have two keys, and b) word searches have two dimensions.
$rc[$r][$c] = $characters[mt_rand(0,$max)];
So, let's start at the beginning with everything rearranged. Please note that I have rewritten things to start your row/column count at 0 instead of 1 because that's the programming convention for arrays, and I'm not going to try to bend my brain around counting from 1 just for this.
$wrdList =array('four', 'banana', 'howl');
$row = 5; //six rows counting from 0
$col = 5; //six columns counting from 0
$rc = array(); //our tableau array
$directions = array('H', 'V', 'D');
foreach ($wrdList as $wrd)
{
$found = false; // by default, no spot has been found
$tries = $row*$col; // we will try a reasonable number of times to find a spot
while(!$found && $tries > 0) {
$wrdLen = strlen($wrd);
$dir = $directions[mt_rand(0,2)];
if ($dir =="H")
{
$limitRow = $row;
$limitCol = $col - ($wrdLen - 1);
}
elseif($dir=="D")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col - ($wrdLen - 1);
}
elseif ($dir=="V")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col;
}
$temprow = mt_rand(0,$limitRow);
$tempcol = mt_rand(0,$limitCol);
//this is my temporary placement array
$placement = array();
//let's use for loop so we can capitalize on having numeric keys
$r = $temprow;
$c = $tempcol;
for($w = 0; $w < $wrdLen; $w++) {
$thisChar = $wrd{$w};
//find array keys
if($dir == 'V' || $dir == 'D') {
$r = $temprow + $w;
}
if($dir == 'H' || $dir == 'D') {
$c = $tempcol + $w;
}
//look at the current tableau
if(isset($rc[$r][$c])) { //the intended spot has a letter
if($rc[$r][$c] == $thisChar) { //the intended spot's letter is the same
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
} else {
break; //this path doesn't work
}
} else {
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
}
}
if($found) {
//put the letters out of the temporary array and into the tableau
foreach($placement as $r=>$set) {
foreach($set as $c=>$letter) {
$rc[$r][$c] = $letter;
}
}
}
$tries--;
}
//handle the error where no spot was found for the word
if(!$found) {
//your error handling here
}
}
//random fillers
$characters = range('a','z');
$max = count($characters) - 1;
for($r = 0; $r <= $row; $r++) {
for($c = 0; $c <= $col; $c++) {
if(!isset($rc[$r][$c])) {
$rc[$r][$c] = $characters[mt_rand(0,$max)];
}
}
}

Categories