Checking repeating combination - php

So I have a program in PHP, which draws three numbers from array, adds them up and checks if sum = 10. If yes, then it should print those numbers on the display.
What I want to do is to check which combination was drawn. For example:
First draw: 1+7+2
Second draw: 5+4+1
Third draw: 1+2+7
First and third had the same numbers, so third shouldn't be shown. Unfortunately, I have no idea how to do it.
My code:
<?PHP
$numb = array(1,2,3,4,5,6,7,8,9,0);
$hm = count($numb);
for ($a=0; $a<$hm;$a++)
for ($b=0; $b<$hm;$b++)
for ($c=0; $c<$hm;$c++)
{
$cnt = $numb[$a]+$numb[$b]+$numb[$c];
if ($cnt == 10)
{
print_r ($numb[$a]);
echo "+";
print_r ($numb[$b]);
echo "+";
print_r ($numb[$c]);
echo "<br>";
}
}
?>

With the provided code, you can simply draw numbers "in order" to avoid duplicates:
$numb = array(0,1,2,3,4,5,6,7,8,9); // <-- must be sorted from lowest to highest
for ($a = 0; $a < $hm; $a++)
for ($b = $a; $b < $hm; $b++) // <-- start from $a
for ($c = $b; $c < $hm; $c++) // <-- start from $b
Thus, the combination 1+2+7 is possible, but not 1+7+2, and also not 7+1+2 etc.

Related

PHP calculating two arrays and then add their sum

I want to calculate an array to another array and then add both like this :
Array1(4,8,7,12);
Array2(3,6);
the result is like this :
3x4+3x8+3x7+3x12+6x4+6x8+6x7+6x12 = 279
I tried with this code and since I'm still new with php I still didn't make any tips I'll be glad thanks in advance
<?php
tab1(4,8,7,12);
tab2(3,6);
$s=0;
for($i=0; $i<$tab1[3]; $i++){
for($j=0; $j<$tab2[1]; $j++){
$s = $s + tab[i] * tab[j];
}
echo "$s";
}
?>
This is actually a piece of cake. I am not sure what tab1 means but I assume you are trying to use this function to get an array of desired(input) numbers.
Using a foreach loop to loop over the two arrays, I came up with the code below:
<?php
$a = [4,8,7,12];
$b = [3,6];
$sum = 0;
foreach ($b as $valueInB) {
foreach ($a as $valueInA) {
$sum += $valueInA * $valueInB;
}
}
echo $sum;
?>
which results in:
279
if you are insisting on using a for loop you can run the code below to get the same result:
<?php
$a = [4,8,7,12];
$b = [3,6];
$sum = 0;
$bLength = count($b);
$aLength = count($a);
for ($i=0; $i < $bLength ; $i++) {
$valueInB = $b[$i];
for ($j=0; $j < $aLength ; $j++) {
$valueInA = $a[$j];
$sum += $valueInA * $valueInB;
}
}
echo $sum;
?>
Please note that you should use the count outside of the loop because looping over the array and calling count each time is not an efficient way. (Thanks to Will B for the comment)
For a more simplistic approach without iteration you can use array_sum on the two arrays.
Example: https://3v4l.org/3gtgE
$a = [4,8,7,12];
$b = [3,6];
$c = array_sum($a) * array_sum($b);
var_dump($c);
Result
int(279)
This works because of the order of operations of:
(3*4) + (3*8) + (3*7) + (3*12) + (6*4) + (6*8) + (6*7) + (6*12) = 279
Equates to the same as the sum of a multiplied by the sum of b:
(4+8+7+12) * (3+6) = 279

List of numbers until n divisible by A or B but not divisible by C

I have three integers: A, B, C
I want to print all integers from 1 to range which are divisible by A or B but not by C.
My code
for($n=0; $n < $range; $n++){
if(($n < $a && $n < $b) || ($n % $c == 0)){
return [];
}
if(($n % $a == 0 || $n % $b == 0) && ($n % $c > 0)){
$outputArr[] = $n;
}
}
Is there any more efficient way to do this?
You can speed this up but it is more complicated, especially if you must print these out in order. Here is a method that doesn't print them out in order.
First write a greatest common divisor (gcd) function in PHP, and then write a least common multiple (lcm) function that uses the gcd function. Compute m = lcm(a, b). Iterate over multiples of a and print them out if they are not divisible by c. Next, iterate over multiples of b and print them out if they are not divisible by m or c.
Other optimizations along these lines are possible. For example, you can precompute the multiples of a or b that are not multiples of m and store them in an array. This works if m is not too large, division is more expensive than array access in PHP, and range is significantly larger than m.
PHP version 7 or higher is so fast when only integer operations are used that micro-optimizations are no longer needed.
$res = [];
$a = 9;
$b = 13;
$c = 26;
$range = 10000;
for($n=$a; $n <= $range; $n += $a){
if($n%$c != 0) $res[] = $n;
}
for($n=$b; $n <= $range; $n += $b){
if($n%$c != 0) $res[] = $n;
}
$res = array_unique($res);
sort($res);
This example takes about 1 millisecond to calculate the 1411 values on my 8-year-old system. This time for the presentation of the result is several times greater.
I would use range() and array_filter().
$range = 20;
$A = 2;
$B = 3;
$C = 9;
$nums = array_filter(range(1, $range), function ($x) use ($A, $B, $C) {
return (!($x % $A) || !($x % $B)) && $x % $C;
});
var_dump($nums);
Here is a more optimized solution, that also works efficient when a and b are large. You can simply run through the multiples of a and b:
for($na=$a, $nb=$b; $na <= $range || $nb <= $range; ){
if ($na <= $nb) {
if ($na % $c != 0)
$outputArr[] = $na;
if ($na == $nb)
$nb += $b;
$na += $a;
} else {
if ($nb % $c != 0)
$outputArr[] = $nb;
$nb += $b;
}
}
Each output number is only generated once, and already in the desired order.
If you are afraid the modulo test is slow, you could also have a next multiple of c running along, but that looks like too much overhead.

PHP float comparison

I have the following PHP code in which I want to compare two decimal numbers. I have read in the PHP documentation that floating point numbers have limited precision.
$a = 0.0;
for ($i = 0; $i < 10; $i++) {
$a += 0.1;
}
var_dump($a);
echo gettype($a);
if ($a === 1.0) {
echo "IF";
} else {
echo "ELSE";
}
When I compare variable $a with 1.0, it always returns false, and the result will be 'ELSE'. My question is how I can get the code above working properly.
you can just do it this way:
//just a check if it is float, than round it to 1 decimal number and compare
if(is_float($a)){
echo 'not a float';
$a = round($a,1);
}
and output will be 'IF'
This question has been asked before, see Compare floats in PHP.
Basically you need to calculate the difference and see if it is small enough to be acceptable as "equal".
Try something like this:
$a = 0.0;
for ($i = 0; $i < 10; $i++) {
$a += 0.1;
$a=number_format($a,1);
//echo gettype($a);
//echo $a.'<br>';
if (floatval($a) === 1.0)
echo "IF";
else
echo "ELSE";
}
In order to make the comparison work I would truncate $a to one decimal place and format $a to a string with the required precision and compare it to "1.0".
To truncate $a I suggest reading this answer .
Or you can use $a as an integer. Them instead of incrementing by 0.1 use 1. And use 10 in the final comparison.

Count from 3 in 3 until I reach 10 with php

I am trying a basic program to count from 3 in 3 until I reach 10. I tried:
<?php
$a = 0;
$b = 0;
while ($a < 10) {
$a += $b + 3;
echo "$a\n\r";
}
?>
The output is 3, 6, 9, 12. And the expected output would be 3, 6, 9. because I added < 10. Why is it doing this? Sorry for my noob question, but it's confusing: http://codepad.org/Y8yhd0JP
The value of $a is $a=9 in the 3rd iteration, so the loop will continue to go on to add upto 12.
To obtain the result as 3,6,9 check for while($a < 9){...}
<?php
$a = 0;
$b = 0;
while ($a < 9) {
$a += $b + 3;
echo "$a\n\r";
}
?>
This would be better to do with a do-while cycle, with $a initialised to its starting value before the cycle
<?php
$b = 0;
$a += $b + 3;
do {
echo "$a\n\r";
$a += $b + 3;
} while ($a < 10);
?>
The while will check if the value in $a is more than 10.
After the check you add to the value and print it, then check again, if its over 10, it will not do another loop.
So when it prints 12, it will have checked if $a was over 10, which is was not, cause it was 9. Then do the addition and echo and check again and exit.
To start with, note the $b is always 0, so you can eliminate it like this:
$a = 0;
while ($a < 10) {
$a += 3;
echo "$a\n\r";
}
Note that you change the value of $a between the test and the echo. That is probably the reason for your surprise.
A better way to write it would be
for ($a = 3; $a < 10; $a += 3) {
echo "$a\r\n";
}
An uglier solution:
$a = 0;
$b = 0;
while (($a += $b + 3) < 10)
echo "$a\n\r";
I moved the addition in the while loop. Here you dont't have to put the echo in {} because there's only one statement.
in your code you are printing the element after it is increased, so after it prints 9 , it checks the condition ($a < 10) , the condition is true so it proceeds and print 12 , while the next iteration the condition ($a < 10) fails and it stops. this is the reason , you can avoid it by changing your code as follows,
<?php
$a = 0;
$b = 0;
while ($a < 9) {
$a += $b + 3;
echo "$a\n\r";
}
?>
Hope it helps.

Getting specific numbers in for loop

I want to get 3 int values in a for loop connected with each other. What I basically want is this:
000
001
002
003
010
011
...
323
330
331
I want to have each of the 3 numbers in a variable starting from 0 and max 3 when it gets higher than 3 it increases the number left to it by 1
For example
for($i = 0; $i <= $array; $i++){
echo $a . $b . $c . "<br />"; //Output would be the example I showed above
}
You can use base_convert to convert between arbitrary bases, in your case base 4.
for($i=0, $max = base_convert(333, 4, 10); $i < $max; ++$i) {
echo base_convert($i, 10 , 4);
}
To get 0-padded output, use printf with a format specifier:
printf('%03d', base_convert($i, 10 , 4));
for($i = 0; $i <= 63; $i++){
$c = $i % 4;
$b = ($i - $c)/4 % 4;
$a = (($i - $c)/4 - $b)/4;
echo $a . $b . $c . "<br />"; //Output would be the example I showed above
}
It's really just an explicit version of knittl's answer. The for loop has us step through every number from 0 thru 63, which happens to correspond with 0 through 333 in base 4. We then take $i, which is in base 10, and convert it to base 4 step by step. The % is the modulo operator - it returns the remainder after division. The least significant char is simply the remainder of $i/4, so we save that as $c. The next char is the 4 place (like the 10 place in base 10). So we subtract $c, which is already accounted for and divide by 4 and do the same thing.
for($a = 0; $a <= 3; $a++){
for($b = 0; $b <= 3; $b++){
for($c = 0; $c <= 3; $c++){
echo $a . $b . $c . "<br />";
}
}
}
Try this:
$count = 20; //how many numbers do you want
for($i =0; $i<$count; $i++) {
echo str_pad(base_convert($i, 10, 4),3,'0' , STR_PAD_LEFT) . '<br/>';
}
base_convert() converts every $i value from 10 base to 4.
str_pad() fill it with '0' to given length (3 here).
STR_PAD_LEFT means that zeros should be added on left side.

Categories