How to do PHP loops correctly - php

Write a class called math. It is to have one property called num. It also has one method (function) called factorial. This method is to start at 1 and multiply all of the integers to num. If num is 5 then you would multiply 1*2*3*4*5. Of course you are to do this in a loop.
Which loop should I use? For or do while? Also, do I need an inner loop?
I started with
For (i = 1; i <= 5; i++)
{
}
however, i'm stuck on what to do next...any suggestions?

You can do it using any loop. for loop can be converted to while and do .. while and opposite is true too.
for(i=0;i<5;i++)
is same as
i=0; while(i<5){i++;}
To to find the factorial you should multiply all the values from 1 to the number you want factorial of. So if $num = 5. Only one single loop is needed. You'd want to run this loop.
for($i=1;$i<$num;$i++){
$num*=$i;
}
I am not giving a full solution here because the question seems homework. If I give you full solution it will be spoon-feeding.

$result = 1;
$target = 5;
for ($i = 1;$ i <= $target; $i++)
{
$result *= $i;
}
echo $result;
or
$result = 1;
$target = 5;
while($target > 0) {
$result *= $target;
$target--; // You could do this all in one line, but for learners, this is clearer.
}
echo $result;

Each iteration you will want to multiply the total of the factorial by the value of $i
class Math {
public static function Factorial($factorial) {
$output = 1;
for($i = 2; $i <= $factorial; $i++)
$output *= $i;
return $output;
}
}

I've gotten to where I prefer the while(i--) loop:
<?php
class Math {
public $num = 0;
public function factorial() {
$result = 1;
$num = $this->num;
while ($num) {
$result *= $num--;
}
return $result;
}
}
$factor = new Math();
$factor->num = 5;
echo $factor->factorial();
?>
http://codepad.org/hUOgAoz2

Related

PHP -- How to multiple random numbers?

Very new to coding here. Trying to get five random numbers in a range from -10 to 10 generated at once. I have another .php file in which I use the roll_num function, but I'm trying to avoid writing the function 5 different times.
Here is what I currently have:
function roll_num()
{
for ($result = 0; $result <= 5; $result++)
{
$result = [];
$result = rand(-10, 10);
return $result;
}
}
Looking for the simplest way to write this. Help would be useful as I don't know what I'm doing, and this is for an introductory class lol. The way I'm trying is similar to the class example, so I'd like to keep it about the same so that I can follow alongside the course without getting too lost. (Besides what I need to change, of course!) Thanks in advance!
The problem with your code is the return inside of the for loop. As soon you hit the return command the function will exit returning the current value of the result, with only one element. Your return should be out of the for loop.
Try something like this:
<?php
function roll_num()
{
$result = []; // result should start empty
while (count($result) < 5)
{
// every step of the loop should add random value to the array
$result[] = rand(-10, 10);
}
// after all random values were pushed, you return once
return $result;
}
var_export(roll_num());
// http://sandbox.onlinephpfunctions.com/code/cd35d6d65f763963216423f341a4299ce1cee8fe
In your code, you are saving the random number in a variable result and immediately returning it. You should keep an array outside the loop and add numbers to it iteratively. Also the iterator should be a seperate integer not your array itself which should end at index 4.
<?php
function roll_num()
{
$result = [];
for ($i = 0; $i < 5; $i++)
{
$result[] = rand(-10, 10);
}
return $result;
}
print_r(roll_num());
function roll_num()
{
$min = -10;
$max = 10;
$num = 5;
$count = 0;
$return = [];
while ($count < $num) {
$return[] = mt_rand($min, $max);
$return = array_flip(array_flip($return));
$count = count($return);
}
shuffle($return);
return $return;
}
print_r(roll_num());

PHP: Getting random combinations to specified input

I am trying to display possibilities for additions of specific numbers but have not been getting the right results.
<?php
$num3 = 20;
$set = null;
$balance = $num3;
$dig = mt_rand(1,5);
for($i = $balance; $i > 0; $i -= $dig ){
echo $dig.'<br>';
if($i < 1){
$set .= $i;
$balance = 0;
}
else{
$set .= $dig.'+';
$dig = mt_rand(1,5);
}
}
echo $set.'='.$num3;
?>
Here are some of the outputs:
2+5+1+4+5+3+=20
1+4+3+5+3+=20
3+1+1+2+3+4+4+1+3+=20
Appreciate any pointers. Thank in advance...
Ok, even though the requirement isn't completely clear, here's an approach:
(edit: demonstrating prevention of endless loop)
$max_loops = 1000;
$balance = 20;
$found = [];
while($balance > 0 && $max_loops-- > 0) {
$r = mt_rand(1, 5);
if ($balance - $r >= 0) {
$found[] = $r;
$balance -= $r;
}
}
echo implode(' + ', $found) . ' = '.array_sum($found);
Note: This code has a small risk of getting caught in an endless loop... though it's doubtful that it'll ever happen :)
Edit: Now the loop contains a hard-limit of 1000 iterations, after which the loop will end for sure...
To provoke an endless loop, set $balance = 7 and modify mt_rand(4, 5).
You can use a recursive function for this:
function randomAddends($target, $maxAddend = 5, $sum = 0, $addends = [])
{
// Return the array of addends when the target is reached
if ($target <= $sum) {
return $addends;
}
// generate a new random addend and add it to the array
$randomAddend = mt_rand(1, min($maxAddend, $target - $sum));
$addends[] = $randomAddend;
// make the recursive call with the new sum
return randomAddends($target, $maxAddend, $sum + $randomAddend, $addends);
}

Convert GMP integer to a sum of power of two (2n)

I'm using GMP library of php to solve a problem of formulary.
public function gmp_sum($aRessource)
{
// Avec le while
$i = 0;
$nb_ressource = count($aRessource);
while ($i < $nb_ressource)
{
if ($i == 0)
{
$tmp = gmp_init($aRessource[$i]);
}
else
{
$tmp = gmp_add(gmp_init($aRessource[$i]),$tmp);
}
$i++;
}
return $tmp;
}
The variable $aRessource is equal to : array(1,2,4,8);
so my function gmp_sum is returning 15.
I want to create an algorithm who does the reverse operation, the function take the integer 15 and return me an array who contains 1 2 4 8. But I do not know where to start.
Thanks for the help
Solution :
Decompose integer to power of 2 in php
public function gmp_reverse($gmp_sum)
{
$res = array();
$i = 1;
while ($i < 64) // 64 bytes
{
$tmp = $gmp_sum & $i; // check if bytes equal to 1
if ($tmp != 0)
{
array_push($res,$i);
}
$i = $i * 2;
}
return $res;
}
Assuming you want an array which adds up to the sum, you want a reverse of that. This function assumes, you have a perfect input, so for example, 17 will not work.
Try it out.
function reversegen($gmpsum)
{
$stack = array();
$limit = $gmpsum;
$cur = 1;
for($sum = 0; $sum < $limit; )
{
echo $cur. "<br>";
array_push($stack,$cur);
$sum = $sum + $cur;
$cur = 2 * $cur;
}
return($stack);
}
$stack = reversegen(15);
print_r($stack);
15 above is for representative purpose. You can use, 31, 63, 127 etc and it will still work fine.

How to return array in php?

How to return array in php ? Actually I want to return whole value of $x[] insted of last index of $x[]. Please help me...
<?php
function top() {
require './php/connection.php';
$sql = "SELECT * FROM tbl_add";
$query = mysqli_query($connect, $sql);
$n = 0;
while ($result = mysqli_fetch_assoc($query)) {
$a[$n] = $result['add_id'];
$n = $n + 1;
}
$n = $n - 1;
for ($j = 0; $j < $n; $j++) {
for ($i = 0; $i < $n - 1 - $j; $i++) {
if ($a[$i] > $a[$i + 1]) {
$tmp = $a[$i];
$a[$i] = $a[$i + 1];
$a[$i + 1] = $tmp;
}
}
}
for ($i = 0; $i <= $n; $i++) {
echo $a[$i] . '<br>';
}
$j = 1;
for ($i = 0; $i <= 5; $i++) {
$r = $a[$i];
$sql = "SELECT * FROM tbl_add WHERE add_id='$r'";
$query = mysqli_query($connect, $sql);
$result = mysqli_fetch_assoc($query);
if ($result) {
$x[] = $result['mail'];
return $x[];
}
}
}
?>
return $x[]; is invalid syntax.
In expression $x[] = $result['mail'];, $x[] doesn't mean "the last element of $x". It is just a courtesy of PHP that spares the programmer of writing $x[count($x)]1 instead.
Returning an array is as easy as return $x; (given $x is an array).
Btw, there is no place in your code where $x is initialized as array. You just add values to some variable that doesn't exist, using the array syntax. PHP helps you and creates an array first and stores it in the $x variable but this practice is strongly discouraged. You should add $x = array(); somewhere before you use $x for the first time (outside the loop, of course). For example, you can put it before the line for ($i = 0; $i <= 5; $i++) {.
`
1 This statement is not entirely correct. However, if the values are added to the array using only the $x[] = ... syntax (as it happens in the posted code) then it is correct.
You have to return $x
Then when you call this function $data = top();
Now you get return data of function top to variable name data
// the code below will return $x as it is, independent of what it is. Array, integer, string etc..
Return $x;
// if you need to return two values use:
Return array($x, $y);
// again bit variables are returned as they are.
To call the function and get the values/array use:
$array = top();
Var_dump($array); //should be $x from your function

Calculate from an array the number that is equal or higher and closest to a given number

I need to calculate from a given array the number that is equal or higher and closest to a given number in PHP. Example:
Number to fetch:
6.85505196
Array to calculate:
3.11350000
4.38350000
4.04610000
3.99410000
2.86135817
0.50000000
Only correct combination should be:
3.99410000 + 2.86135817 = 6.85545817
Can somebody help me? It's been 3 hours I'm getting mad!
UPDATE: I finally finished my code as following:
$arr = array(3.1135, 4.3835, 4.0461, 3.9941, 2.86135817, 0.5);
$fetch = 6.85505196;
$bestsum = get_fee($arr, $fetch);
print($bestsum);
function get_fee($arr, $fetch) {
$bestsum = 999999999;
$combo = array();
$result = array();
for ($i = 0; $i<count($arr); $i++) {
combinations($arr, $i+1, $combo);
}
foreach ($combo as $idx => $arr) {
$sum = 0;
foreach ($arr as $value) {
$result[$idx] += $value;
}
if ($result[$idx] >= $fetch && $result[$idx] < $bestsum) $bestsum = $result[$idx];
}
return $bestsum;
}
function combinations($arr, $level, &$combo, $curr = array()) {
for($j = 0; $j < count($arr); $j++) {
$new = array_merge($curr, array($arr[$j]));
if($level == 1) {
sort($new);
if (!in_array($new, $combo)) {
$combo[] = $new;
}
} else {
combinations($arr, $level - 1, $combo, $new);
}
}
}
I hope the following example might help you. Please try this
<?php
$array = array(
"3.11350000",
"4.38350000",
"4.04610000",
"3.99410000",
"2.86135817",
"0.50000000"
);
echo "<pre>";
print_r($array);// it will print your array
for($i=0; $i<count($array); $i++)
{
$j=$i+1;
for($j;$j<count($array); $j++)
{
$sum = $array[$i] + $array[$j];
// echo $array[$i]. " + ".$array[$j]." = ".$sum."<br>"; //this will display all the combination of sum
if($sum >= 6.85505196 && ($sum <= round(6.85505196)) )//change the condition according to your requirement
{
echo "The correct combinations are:<br/><br/>";
echo "<b>". $array[$i]. " + ".$array[$j]." = ".$sum."<b>";
echo "<br/>";
}
}
echo "<br/>";
}
?>
We will get the result as below
Array
(
[0] => 3.11350000
[1] => 4.38350000
[2] => 4.04610000
[3] => 3.99410000
[4] => 2.86135817
[5] => 0.50000000
)
The correct combinations are:
4.04610000 + 2.86135817 = 6.90745817
3.99410000 + 2.86135817 = 6.85545817
You should do it in two steps:
a. Work out (or look up) an algorithm to do the job.
b. Implement it.
You don't say what you've managed in the three hours you worked on this, so here's a "brute force" (read: dumb) algorithm that will do the job:
Use a variable that will keep your best sum so far. It can start out as zero:
$bestsum = 0;
Try all single numbers, then all sums of two numbers, then all sums of three numbers, etc.: Every time you find a number that meets your criteria and is better than the current $bestsum, set $bestsum to it. Also set a second variable, $summands, to an array of the numbers you used to get this result. (Otherwise you won't know how you got the solution). Whenever you find an even better solution, update both variables.
When you've tried every number combination, your two variables contain the best solution. Print them out.
That's all. It's guaranteed to work correctly, since it tries all possibilities. There are all sorts of details to fill in, but you can get to work and ask here for help with specific tasks if you get stuck.
Thank you all for your help!
My code is working pretty cool when is needed to fetch one or two numbers (addition) only. But can't figure out how to add more combinations up to the total count of elements in my given array.
I mean if there are, let's say, 8 numbers in my array I want to try all possible combinations (additions to each other) as well.
My actual code is:
$bestsum = 1000000;
for ($i = 0; $i < count($txinfo["vout"]); $i++) {
if ($txinfo["vout"][$i]["value"] >= $spent && $txinfo["vout"][$i]["value"] < $bestsum) {
$bestsum = $txinfo["vout"][$i]["value"];
}
}
for($i = 0; $i < count($txinfo["vout"]); $i++) {
$j = $i + 1;
for($j; $j < count($txinfo["vout"]); $j++) {
$sum = $txinfo["vout"][$i]["value"] + $txinfo["vout"][$j]["value"];
if($sum >= $spent && $sum < $bestsum) {
$bestsum = $sum;
}
}
}
$fee = bcsub($bestsum, $spent, 8);
print("Fee: ".$fee);
New updated code.
<?php
$x = 6.85505196;
$num = array(3.1135, 4.3835, 4.0461, 3.9941, 2.86135817, 0.5);
asort($num); //sort the array
$low = $num[0]; // lowest value in the array
$maxpossible = $x+$low; // this is the maximum possible answer, as we require the number that is equal or higher and closest to a given number
$num = array_values($num);
$iterations = $x/$num[0]; // possible combinations loop, to equate to the sum of the given number using the lowest number
$sum=$num;
$newsum = $sum;
$k=count($num);
for($j=0; $j<=$iterations; $j++){
$l = count($sum);
for($i=0; $i<$l; $i++){
$genSum = $sum[$j]+$sum[$i];
if($genSum <= $maxpossible){
$newsum[$k] = $genSum;
$k++;
}
}
$newsum = array_unique($newsum);
$newsum = array_values($newsum);
$k = count($newsum);
$sum = $newsum;
}
asort($newsum);
$newsum = array_values($newsum);
for($i=0; $i<count($newsum); $i++){
if($x<=$newsum[$i]){
echo "\nMaximum Possible Number = ".$newsum[$i];
break;
}
}
?>

Categories