I use the following to find out the common divisors.
But in some case the count of divisors are not satisfied.
My Code :
$x = 66928;
$y = 66992;
$c_a = [];
$c_b = [];
$d = 1;
while ($d_a <= $x) {
if (is_int($x / $d)) $c_a[] = $d;
$d++;
}
$d = 1;
while ($d_b <= $y) {
if (is_int($y / $d)) $c_b[] = $d;
$d++;
}
echo count($c_a);
echo count($c_b);
// Output
$c_a = 20;
$c_b = 20;
Because, in some cases, it won't work.
Is this type of calculation is right ?
or any suggestions ?
As per asked in comment, to count the common factors of the two no. will be as like this.
<?php
$a = 66928;
$b = 66992;
$min = ($a < $b ) ? $a : $b;
$commomn_factors_count = 0;
for ($i = 1; $i < $min/2; $i++) {
if (($a%$i==0) && ($b%$i==0)) {
$commomn_factors_count++;
}
}
var_dump($commomn_factors_count);
You can you this code to get the fastest result to find the number of common divisors between two numbers:
// Function to calculate gcd of two numbers
function gcd($a, $b)
{
if ($a == 0)
return $b;
return gcd($b % $a, $a);
}
/* Function to calculate all common
* divisors of two given numbers
* a, b --> input integer numbers
*/
function commDiv($a, $b)
{
// find gcd of a, b
$n = gcd($a, $b);
// Count divisors of n.
$result = 0;
for ($i = 1; $i <= sqrt($n);
$i++)
{
// if 'i' is factor of n
if ($n % $i == 0)
{
// check if divisors
// are equal
if ($n / $i == $i)
$result += 1;
else
$result += 2;
}
}
return $result;
}
// Driver Code
$a = 10; $b = 15;
echo(commDiv($a, $b));
Related
Note to moderators: This is not a homework assignment.
I have the following example:
$points = 10;
$a = 0;
$b = 0;
$c = 0;
$d = 0;
I want to randomly distribute the points to the variables ($a,$b,$c,$d) until $points reach zero. So, expected random output after running some function/script should look like this:
$points = 0;// Must be zero
$a = 3;
$b = 1;
$c = 0;
$d = 6;
I'm thinking of doing a simple solution, which is the following:
while($points > 0) {
$points_taken = mt_rand(0, $points);
$points -= $points_taken;
$a += $points_taken;
$points_taken = mt_rand(0, $points);
$points -= $points_taken;
$b += $points_taken;
$points_taken = mt_rand(0, $points);
$points -= $points_taken;
$c += $points_taken;
$points_taken = mt_rand(0, $points);
$points -= $points_taken;
$d += $points_taken;
}
The function has 1 problem: $a has much more higher chance of taking more points (or even all points) because it's first in the list, while $d has much more higher chance of taking less points (or no points at all) because it's last in the list.
Question: How can I give all variables equal chance of distribution?
Note: It's fine if one of the variables took all the points.
You can use randomly select one of the variables from a range, and assign to it using a variable variable.
$vars = range('a','d');
while ($points) {
$points_taken = mt_rand(0, $points);
$points -= $points_taken;
${$vars[mt_rand(0, 3)]} += $points_taken;
}
Something like this?
$points = 10;
$a = 0;
$b = 0;
$c = 0;
$d = 0;
for($i=0; $i<$points; $i++) {
$rand = rand(1,4);
if($rand == 1) {
$a++;
} else if ($rand == 2) {
$b++;
} else if ($rand == 3) {
$c++;
} else if ($rand == 4) {
$d++;
}
}
I am trying to make an array of all the possible colours made out of RGB values. Every permutation between r=0 b=0 g=0 to r=255 b=255 g=255. The idea of my function is that when it's called you supply a limit number so that the function returns an array of RGB values up to this number to stop it returning all 16 million. The code I have below returns 767 permutations (256 * 3) how do I get this to return the full 16 million up to the limit number I provide?
function colourArray($number) {
$r = 0;
$g = 0;
$b = 0;
$i = 0;
while ($i <= $number) {
$colours[] = array($r,$g,$b);
$r++;
$i++;
}
$i = 0;
while ($i <= $number) {
$colours[] = array($r,$g,$b);
$g++;
$i++;
}
$i = 0;
while ($i <= $number) {
$colours[] = array($r,$g,$b);
$b++;
$i++;
}
return $colours;
}
Nesting your loops is the trick. Try the following example. I've replaced your while-loops by foreach-loops with the PHP range function, and nested (i.e. loop-inside-a-loop) them inside eachother:
function colourArray($number) {
$colours = array();
foreach(range(0,$number) as $r) {
foreach(range(0,$number) as $g) {
foreach(range(0,$number) as $b) {
$colours[] = array($r,$g,$b);
}
}
}
return $colours;
}
References:
http://php.net/range
http://php.net/manual/en/control-structures.foreach.php
I almost agree with DickW, but I'm partial to for() loops for numeric ranges.
<?php
function color_array($range)
{
$result = array();
for ($r = 0; $r <= $range; $r++) {
for ($g = 0; $g <= $range; $g++) {
for ($b = 0; $b <= $range; $b++) {
$result[] = array($r, $g, $b);
}
}
}
return $result;
}
print_r(color_array(5));
The code below will create an array for all possible combination that can occur when you have four different variables. The variables always need to equal 1. The for loops I have created work and I understand how to make this work for more variables, but can I make this dynamic? I need to have a function that has how many variables there are as a parameter. If there are three variables create the three forloops. If there are 10... create the 10 corresponding for loops to determine all possible combinations.
$anarray2 = array();
for( $a = 1; $a <= 97; $a++ ) {
for( $b = 1; $a + $b <=98 ; $b++ ) {
for( $c = 1; $a + $b + $c <= 99; $c++ ) {
$d = 100 - ( $a + $b + $c );
$var_1 = $a / 100;
$var_2 = $b / 100;
$var_3 = $c / 100;
$var_4 = $d / 100;
$anarray2[] = array( $var_1, $var_2, $var_3, $var_4 );
}
}
}
print_array( $anarray2 );
You're effectively looking to share out I identical items to N people in all of the different possible ways.
If there is one person (N==1), then there is only one way to do this - give that person all I items.
If there is more than one person (N>1), then we can consider how many items can be assigned to the first person, and then what the possible assignments are for the remaining N-1 people in each case.
This leads to a nice recursive solution. Firstly we solve the problem for N=1:
function assign($I, $N) {
$anarray = array();
if ($N == 1) {
$anarray[] = array($I);
} else {
// Coming up...
}
return $anarray;
}
Now we solve the problem for N=k (some constant) in terms of N=k-1 - that is, we solve the problem using the solution to a smaller problem. This will reach all the way back to the solution when N=1.
function assign($I, $N) {
$anarray = array();
if ($N == 1) {
$anarray[] = array($I);
} else {
for ($i = $I; $i < $I; $i++) {
foreach (assign($I - $i, $N - 1) as $subproblem) {
$anarray[] = array_merge(array($i), $subproblem);
}
}
}
return $anarray;
}
Something like that should do the job.
The following code is displaying INF as the result. How can I fix it?
<?php
function fibonacci($n)
{
$a = 1;
$b = 1;
$result = 0;
for ($i = 0; $i < $n; $i=$i+1)
{
$sum = $a + $b;
$a = $b;
$b = $sum;
if ($a % 2 == 0)
{
$result = $result + $a;
}
}
echo "<br/>" . $result;
}
echo fibonacci(400000);
?>
The number is too big to display, and INF is a pretty good guess :) (fibonacci(1000) gives you a number with 210 digits).
100: 22 digits, 110: 24 digits, 120: 25 digits, 130: 27 digits
If you extrapolate that, you would end up with about (400000 / 10) * 2 = 80000 digits.
The following implements your logic using bcmath to prevent the INF error.
function fibonacci($n)
{
$a = '1'; $b = '1'; $result = '0';
for ($i = 0; $i < $n; $i++) {
$sum = bcadd($a,$b);
$a = $b;
$b = $sum;
if (bcmod($a,'2') == '0') {
$result = bcadd($result,$a);
}
}
echo "<br />".$result;
}
As your fibonacci function doesn't actually return any value, there's no point in echo fibonacci(400000)
EDIT
However, your logic is completely flawed. The following should give you the correct result for the problem you're trying to solve (again using bcmath):
function fibonacci($n)
{
$a = '0'; $b = '1'; $sum = '0';
$sum = '0';
do {
$fib = bcadd($a,$b);
$a = $b;
$b = $fib;
if (bccomp($fib,$n) == -1) {
if (bcmod($fib,'2') == '0') {
$sum = bcadd($sum,$fib);
}
}
++$i;
} while (bccomp($fib,$n) == -1);
return $sum;
}
echo fibonacci(4000000);
Rather than simply executing it to get the result, look to see how it works and what it's actually doing
I've adapted this from an example that I found on the 'net...
function ratio($a, $b) {
$_a = $a;
$_b = $b;
while ($_b != 0) {
$remainder = $_a % $_b;
$_a = $_b;
$_b = $remainder;
}
$gcd = abs($_a);
return ($a / $gcd) . ':' . ($b / $gcd);
}
echo ratio(9, 3); // 3:1
Now I want it to use func_get_args() and return the ratios for multiple numbers. It looks like a recursive problem, and recursion freaks me out (especially when my solutions infinitely loop)!
How would I modify this to take as many parameters as I wanted?
Thanks
1st, try this gcd function http://php.net/manual/en/function.gmp-gcd.php
Or else you must define a gcd function like
function gcd($a, $b) {
$_a = abs($a);
$_b = abs($b);
while ($_b != 0) {
$remainder = $_a % $_b;
$_a = $_b;
$_b = $remainder;
}
return $a;
}
Then modify the ratio function
function ratio()
{
$inputs = func_get_args();
$c = func_num_args();
if($c < 1)
return ''; //empty input
if($c == 1)
return $inputs[0]; //only 1 input
$gcd = gcd($input[0], $input[1]); //find gcd of inputs
for($i = 2; $i < $c; $i++)
$gcd = gcd($gcd, $input[$i]);
$var = $input[0] / $gcd; //init output
for($i = 1; $i < $c; $i++)
$var .= ':' . ($input[$i] / $gcd); //calc ratio
return $var;
}