How can I calculate min, max and average values from random numbers? - php

I have the following code:
<?php
echo "<p>Exercise 5:</p>";
echo "Numbers: ";
$random = 0;
while ($random < 10) {
$rand = rand(2, 80);
echo "$rand";
$random = $random + 1;
if ($random < 10) {
echo ", ";
};
}
echo "<br><br>Min value: <br>";
echo "Max value: <br>";
echo "Average value: <br>";
?>
How can I calculate the min, max and average value of the 10 numbers?
$min = min($rand) doesn't work...
$max = max($rand) doesn't work either...

$rand is a single value, minimum of a single value is irrelevant. Min takes an array as parameter (or several values), so save your values in an array, e.g. like this.
$array = array();
while($random < 10) {
$rand = rand(2, 80);
$array[] = $rand;
$random++; // short for random = random + 1
}
echo min($array);
Works also with max.
Moreover, average = sum / count, you have array_sum and count function in PHP, I let you figure out how to do that.
Edit: Augustin is right about division by zero. Consider adding a condition when making a division by a variable.

One solutions thinking in division by zero could be:
$random = 0;
$numbers = array();
while ($random < 10) {
$rand = rand(2, 80);
echo "$rand";
$numbers[] = $rand;
$random ++;
}
$min = min($numbers);
$max = max($numbers);
if($totalNumbers = count($numbers) > 0) {
$average = array_sum($numbers) / count($numbers);
}else{
$average = 0;
}
echo "<br><br>Min value: $min <br>";
echo "Max value: $max <br>";
echo "Average value: $average <br>";
I don't understand why min or max doesn't work, but in this case, you could make a custom max min function:
function customMaxMin($numbers)
{
$max = 0;
$min = 0;
foreach ($numbers as $number) {
$max = $number;
$min = $number;
if ($max > $number) {
$max = $number;
}
if ($min < $number) {
$min = $number;
}
}
return array('max' => $max, 'min' => $min);
}

Related

PHP search array for a value between two numbers

What's the best way of searching an array for a number within a range? e.g. between 1000 and 1500.
<?php
$numbers = array(1105,2140,3170);
$needle = **value between 1000 and 1500**;
if (in_array($needle, $numbers)) {
echo "Match found";
} else {
echo "Match not found";
}
?>
In this case, this would return 'Match found' as 1105 is between 1000 and 1500.
Can I set a range for the $needle variable?
What's the best way of searching an array for a number within a range. To answer this, there are 2 approaches as mentioned below:
Approach #1:
You can use a simple foreach loop to get all values from your unordered data which lie in the range.
<?php
$numbers = array(1105,2140,3170);
$start = 1000;
$end = 1500;
$result = [];
foreach($numbers as $num){
if($num >= $start && $num <= $end) $result[] = $num;
}
print_r($result);
Demo: https://3v4l.org/D1Rfu
Approach #2:(recommended for future lookups)
You can sort your data and use binary search to get the starting point of where your numbers start falling in the range of start and end for faster lookups. Then, you can just look from that index till the index you get a higher number or reach the end of the array.
<?php
$numbers = array(1105,2140,3170,1000,1500,1501);
$start = 1000;
$end = 1500;
$start_index = -1;
sort($numbers);
$low = 0; $high = count($numbers) - 1;
while($low <= $high){
$mid = intval(($low + $high) / 2);
if($numbers[$mid] > $end){
$high = $mid - 1;
}else if($numbers[$mid] < $start){
$low = $mid + 1;
}else{
$start_index = $mid;
$high = $mid - 1;
}
}
$result = [];
for($i = $start_index; $i < count($numbers); ++$i){
if($numbers[$i] > $end) break;
$result[] = $numbers[$i];
}
print_r($result);
Demo: https://3v4l.org/WcgXv
Yes, you can create a range and use it as the "needle", but not using in_array. You can create a range and compute the intersection of the numbers array. To just check for any match:
$numbers = array(1105, 2140, 3170);
$needle = range(1000, 1500);
if (array_intersect($numbers, $needle)) {
echo "Match found";
} else {
echo "Match not found";
}
Or to get the possible match(es):
$numbers = array(1105, 2140, 3170);
$needle = range(1000, 1500);
$result = array_intersect($numbers, $needle);
Or you can filter out the ones not in the range:
$numbers = array(1105, 2140, 3170);
$min = 1000;
$max = 1500;
$result = array_filter($numbers, function($v) use($min, $max) {
return $v >= $min && $v <= $max;
});
You will get an empty array if there are no matches in either case. Also, you don't state what you want if there is more than one, but you'll get an array in either case so you could use current for one or min and/or max instead:
$one = current(array_intersect($numbers, $needle));
$min = min(array_intersect($numbers, $needle));
$max = max(array_intersect($numbers, $needle));
There is no built-in function for these purpose. So create a function that will help you.
function searchOnRange(array $stack, $min=0, $max=0)
{
// Loop through each value of array
foreach($stack as $value){
// CHeck value is between the given range
if(($value >= $min) && ($value <= $max)){
echo "Match found - ".$value;
} else {
echo "Match not found - ".$value;
}
}
}
$numbers = array(1105,2140,3170);
searchOnRange($numbers, 1000, 1500);

How to create second array and display numbers that are greater than average number of first array?

I want to make second array that gives all numbers using rand function that are greater than average number of first array.
I've created new array and I've tried with if statement to display all numbers greater than average number, and to put those values into a new empty array
$arrNums = array();
$arrNewNums = array();
$intSum = 0;
$intTotalNum = 20;
for($i = 0; $i < $intTotalNum; $i++)
{
$intRand = rand(9, 99);
$arrNums[] = $intRand;
$intSum = $intSum + $arrNums[$i];
$averageNum = $intSum / count($arrNums);
foreach($arrNums as $key => $value)
{
if($value > $averageNum)
{
$arrNewNums[] = rand();
}
}
}
echo '<pre>';
print_r($arrNums);
echo "<br>";
echo "Average number from array is " . $averageNum;
echo "<br>";
print_r($arrNewNums);
I would like to get the output of 20 numbers greater than average number, for example 56.4, but instead of that I'm getting 100 numbers and they are all for example 864165243, 738017258 and so on and so on...
This is the correct code for your task:
$arrNums = array();
$arrNewNums = array();
$intSum = 0;
$intTotalNum = 20;
for($i = 0; $i < $intTotalNum; $i++)
{
$intRand = rand(9, 99);
$arrNums[] = $intRand;
$intSum += $intRand;
}
// count average value AFTER you have all items in array
// $averageNum = array_sum($arrNums) / count($arrNums);
// Without `array_sum`:
$averageNum = $intSum / count($arrNums);
// check values of array AFTER you have all items in array
foreach($arrNums as $value) {
if($value > $averageNum) {
// add `$value` to `$arrNewNums`, not some random variable.
$arrNewNums[] = $value;
}
}
echo '<pre>';
print_r($arrNums);
echo "<br>";
echo "Average number from array is " . $averageNum;
echo "<br>";
print_r($arrNewNums);

Calculate at least 3 minimum and maximum numbers from array

Code
<?php
$array = array("1", "2", "3", "4", "5", "6", "7", "8", "100");
$max = $temp = 0;
$min = $temp = 0;
//This loop is to get max and min value from array
for ($i = 0 ; $i < count($array); $i++) {
if ($i == 0) {
$max = $temp = $array[$i];
}
if ($i > 0) {
if ($array[$i] > $temp) {
$max = $array[$i];
}
}
if ($i == 0) {
$min = $temp = $array[$i];
}
if ($i < 0) {
if ($array[$i] < $temp) {
$min = $array[$i];
}
}
}
echo "Max Number = $max <br>";
echo "Min Number = $min";
?>
The above code only calculates one minimum and one maximum number from the array. I need it to calculate 3 maximum and 3 minimum numbers.
I can't use pre-made functions and can't use more than one for loop so kindly suggest me customization within the above code.
This looks neat to me.
<?php
$array = array("1", "2", "3", "4", "5", "6", "7", "8", "100");
$n1 = $n2 = $n3 = 1000 ; // some high number
$m1 = $m2 = $m3 = 0 ;
//This loop is to get max and min value from array
for ($i = 0 ; $i < count($array); $i++) {
$x = $array[$i] ;
//min
if ($x <= $n1){
$n3 = $n2 ;
$n2 = $n1 ;
$n1 = $x ;
} elseif ($x < $n2){
$n3 = $n2;
$n2 = $x;
} elseif ($x < $n3){
$n3 = $x;
}
//max
if ($x >= $m1){
$m3 = $m2 ;
$m2 = $m1 ;
$m1 = $x ;
} elseif ($x > $m2){
$m3 = $m2;
$m2 = $x;
} elseif ($x > $m3){
$m3 = $x;
}
}
echo "Min Number = $n1 $n2 $n3<br>";
echo "Max Number = $m1 $m2 $m3";
?>
Output:
Min Number = 1 2 3
Max Number = 100 8 7
This code is working properly
<?php
$array = array("1", "2", "3", "4", "5", "6", "7", "8", "100");
$max1 =$max2 =$max3= -999999999999999; // highest possible number
$min3 = $min2= $min1 = 9999999999999999; // lowest possible number
for ($i = 0 ; $i < count($array); $i++) {
$x = $array[$i] ;
//to get the max 3 numbers
if($x>= $max1)
{
$max3 = $max2;
$max2 = $max1;
$max1 = $x;
}
else if ($x> $max2)
{
$max3 = $max2;
$max2 = $x;
}
else if ($x> $max3)
{
$max3 = $x;
}
// to get the min 3 numbers
if($x<=$min3 && $x>$min2 )
{
$min3 = $x;
}
else if ($x<$min2 && $x>$min1)
{
$min3 = $min2;
$min2 = $x;
}
else if ( $x<$min1)
{
$min3 = $min2;
$min2 = $min1;
$min1 = $x;
}
}
echo "Max Number = $max1 , $max2 , $max3 <br>";
echo "Min Number = $min1 , $min2 , $min3";
?>
The output is
Max Number = 100 , 8 , 7
Min Number = 1 , 2 , 3
There are better ways and more efficient than that but which requires 2 loops and u don't want that !
You can handle this using if statements
Checking for the max/min number works when you find another min/max value other than the previous one while looping. This is the algorithm that you use
Lets assume that your min=5
and after looping the current index value is 3, so you will have to make min=3
What about assigning 5 to min2 for example?
Three variables min1, min2, min3, and nested if statements
I know it's not the best way. But have you tried this?
You just need to reverse sort the array and then slice the first three indexes. You could express it as a function:
function topThree(Array $arr) {
// Sort the array in reverse
rsort($arr);
// Return the first three indexes (top three)
return array_slice($arr, 2);
}
See rsort and array_slice
Edit: Okay this works
/**
* Sorts an array of numeric values from largest to
* smallest and returns the three highest values.
*
* #param Array $arr An array of numeric values.
* #return Array $srt The three highest values in $arr.
*/
function topThree(Array $arr) {
$srt = [];
foreach($arr as $key => $val) {
if(!$key) {
$srt[] = $val;
} else if ($val < $srt[0]) {
array_unshift($srt, $val);
} else if ($val > $srt[count($srt)-1]) {
array_push($srt, $val);
} else {
for( $i=1; $i<count($srt); $i++) {
if($val < $srt[$i]) {
array_splice( $srt, $i, 0, $val );
break;
}
}
}
}
$max = array_slice($srt, -3, 3);
$min = array_slice($srt, 0, 3);
return ["min" => $min, "max" => $max];
}
// "Test"
for($i=0; $i<20;$i++){
$arr[]=rand(-100,100);
}
print_r($arr);
print_r(topThree($arr));
If $val's the first $key $val's added to $sort.
If $val's less than $sort[0] $val's added to the start of $sort.
If $val's greater than $sort[length], then $val's added to the end of $sort.
Otherwise, we check every $val against every other $sort value. When we find a $sort[$i] value greater than $val, we splice the array with $val at $i.
Make sense?

how to find highest and second highest number in an array without using max function

I already have solution. But i think it will be more optimizable. So please provide me a solution for it. And remember that don't use predefined function of php. Like max() function.
i know there are so many ways to find it but i want best and better solution. Because my array contains more than 1 lakh records and it's taking lot of time. Or sometime site will be down.
My code :
<?php
$array = array('1', '15', '2','10',4);
echo "<pre>";
print_r($array);
echo "<pre>";
$max = 0;
$s_max=0;
for($i=0; $i<count($array); $i++)
{
$a = $array[$i];
$tmax = $max;
$ts_max = $s_max;
if($a > $tmax && $a > $ts_max)
{
$max = $a;
if($tmax > $ts_max) {
$s_max = $tmax;
} else {
$s_max = $ts_max;
}
} else if($tmax > $a && $tmax > $ts_max)
{
$max = $tmax;
if($a > $ts_max) {
$s_max = $a;
} else {
$s_max = $ts_max;
}
} else if($ts_max > $a && $ts_max > $tmax)
{
$max = $ts_max;
if($a > $tmax)
{
$s_max = $a;
} else {
$s_max = $tmax;
}
}
}
echo "Max=".$max;
echo "<br />";
echo "S_max=".$s_max;
echo "<br />";
?>
<?php
$array = array('200', '15','69','122','50','201');
$max_1 = $max_2 = 0;
for ($i=0; $i<count($array); $i++) {
if ($array[$i] > $max_1) {
$max_2 = $max_1;
$max_1 = $array[$i];
} else if ($array[$i] > $max_2 && $array[$i] != $max_2) {
$max_2 = $array[$i];
}
}
echo "Max=".$max_1;
echo "<br />";
echo "Smax 2=".$max_2;
See this solution.
<?php
$numbers = array_unique(array(1,15,2,10,4));
// rsort : sorts an array in reverse order (highest to lowest).
rsort($numbers);
echo 'Highest is -'.$numbers[0].', Second highest is -'.$numbers[1];
// O/P: Highest is -15, Second highest is -10
?>
I didn't check your solution, but in terms of complexity it's IMO optimal. If the array has no more structural information (like it's sorted) there's no way to skip entries. I.e. the best solution is in O(n) which your solution is.
This is a perfect and shortest code to find out the second largest value from the array. The below code will always return values in case the array contains only a value.
Example 1.
$arr = [5, 8, 1, 9, 24, 14, 36, 25, 78, 15, 37];
asort($arr);
$secondLargestVal = $arr[count($arr)-1];
//this will return 37
Example 2.
$arr = [5];
asort($arr);
$secondLargestVal = $arr[count($arr)-1];
//this will return 5
You can also use techniques in sorting like Bubble sort
function bubble_Sort($my_array )
{
do
{
$swapped = false;
for( $i = 0, $c = count( $my_array ) - 1; $i < $c; $i++ )
{
if( $my_array[$i] > $my_array[$i + 1] )
{
list( $my_array[$i + 1], $my_array[$i] ) =
array( $my_array[$i], $my_array[$i + 1] );
$swapped = true;
}
}
}
while( $swapped );
return $my_array;
}
$test_array = array(3, 0, 2, 5, -1, 4, 1);
echo "Original Array :\n";
echo implode(', ',$test_array );
echo "\nSorted Array\n:";
echo implode(', ',bubble_Sort($test_array)). PHP_EOL;
Original Array :
3, 0, 2, 5, -1, 4, 1
Sorted Array :
-1, 0, 1, 2, 3, 4, 5
Flow explanation
$array = array(80,250,30,40,90,10,50,60,50); // 250 2-times
$max = $max2 = 0;
foreach ($array as $key =>$val) {
if ($max < $val) {
$max2 = $max;
$max = $val;
} elseif ($max2 < $val && $max != $val) {
$max2 = $val;
}
}
echo "Highest Value is : " . $max . "<br/>"; //output: 250
echo "Second highest value is : " . $max2 . "<br/>"; //output: 90
The answer given by "Kanishka Panamaldeniya" is fine for highest value but will fail on second highest value i.e. if array has 2-similar highest value, then it will showing both Highest and second highest value same. I have sorted out it by adding one more level comparsion and it works fine.
$array = array(50,250,30,250,40,70,10,50); // 250 2-times
$max=$max2=0;
for ($i = 0; $i < count($array); $i++) {
if ($array[$i] > $max) {
$max2 = $max;
$max = $array[$i];
} else if (($array[$i] > $max2) && ($array[$i] != $max)) {
$max2 = $array[$i];
}
}
echo "Highest Value is : " . $max . "<br/>"; //output : 250
echo "Second highest value is : " . $max2 . "<br/>"; //output : 70
This code will return second max value from array
$array = array(80,250,30,250,40,90,10,50,60,50); // 250 2-times
$max=$max2=0;
for ($i = 0; $i < count($array); $i++) {
if($i == 0) {
$max2 = $array[$i];
}
if($array[$i] > $max) {
$max = $array[$i];
}
if($max > $array[$i] && $array[$i] > $max2) {
$max2 = $array[$i];
}
}
echo "Highest Value is : " . $max . "<br/>"; //output : 250
echo "Second highest value is : " . $max2 . "<br/>"; //output : 90
Two way find the second highest salary
1. Sort the data in Descending order
2. get array first value
3. Check the condition already comments
$array = [2,3,6,11,17,14,19];
$max = $array[0];
$count = count($array);
for($i=0; $i<$count;$i++)
{
for($j=$i+1;$j<$count;$j++)
{
if($array[$i] < $array[$j])
{
$temp = $array[$i];
$array[$i] = $array[$j];
$array[$j] = $temp;
}
}
}
First Method
//echo $array[1]; // Second highest value
$second ='';
for($k=0;$k<2;$k++)
{
if($array[$k] >$max)
{
$second = $array[$k];
}
}
echo $second; // Second method
Without using MAX function. Here.
$arr = [3,4,-5,-3,1,0,4,4,4];
rsort($arr); // SORT ARRAY IN DESCENDING ORDER
$largest = $arr[0]; // IN DESCENDING ORDER THE LARGEST ELEMENT IS ALWAYS THE FIRST ELEMENT
$secondLargest = 0;
foreach($arr as $val){
$secondLargest = $val; // KEEP UPDATING THE VARIABLE WITH THE VALUE UNTIL IT RECEIVES THE FIRST ELEMENT WHICH IS DIFFERENT FROM THE LARGEST VALUE
if($val != $arr[0]){
break; // BREAK OUT OF THE LOOP AS SOON AS THE VALUE IS DIFFERENT THAN THE LARGEST ELEMENT
}
}
echo $secondLargest;

Divide a number into equal parts and store their cumulative sum

Simple question, how do I get every option when dividing a number? For example:
24 by 6 returns 6, 12, 18, 24
24 by 4 returns 4, 8, 12, 16, 20, 24
24 by 5 returns false
I've got a number in my database, for example 2, and my counter, for example 14. That means every time my counter hits the second number, I want to fire my event. So I thought, if I have the solutions 2, 4, 6, etc, and my counter is equal to one of the solutions, I can fire my event.
It's rather trivial to make.
<?php
/**
* #param int $number The beginning number
* #param int $divider The number dividing by
*
* #return array
* #throws Exception In case $number is not divisible by $divider
*/
function get_number_sequence($number, $divider) {
//In case $number is not divisible by $divider, throw an Exception.
if ($number % $divider !== 0) {
throw new Exception("$number is not divisible by $divider");
}
//Return an array from $divider to $number in steps of $divider.
$result = range($divider, $number, $divider);
return $result;
}
/*
* Testing begins
*/
try {
echo "<pre>";
echo implode(", ", get_number_sequence(24, 4)) . PHP_EOL;
echo implode(", ", get_number_sequence(24, 6)) . PHP_EOL;
echo implode(", ", get_number_sequence(24, 5)) . PHP_EOL;
echo "</pre>";
}
catch (Exception $e) {
echo "Invalid: " . $e->getMessage();
}
Some Points
Don't return false if something exceptional happens, use an Exception as shown in the example.
Use the modulus operator to determine if the number is divisible or not.
Return an array, not a string. It's easier to work with.
should be easy
do a modulus on X by Y . If 0 then do a division on X by Y. create a loop which will run from 1 to (division on X by Y) and output Y multiplied by the loop counter
function steps($target,$step) {
if (($target % $step) != 0)
return FALSE;
$steps = range($step,$target,$step);
return $steps;
}
$target = 24;
for ($step = 2; $step < 13; ++$step) {
echo '$step = ',$step,PHP_EOL;
$steps = steps($target,$step);
var_dump($steps);
}
function findQuotients($number, $divider)
{
$arr = array();
if($number % $divider != 0)
{
//return "false";
}
else
{
$loop = $number / $divider;
//$output="";
for($i = 1; $i <= $loop; $i++)
{
//$output .= $i * $divider. " ";
array_push($arr, $i * $divider);
}
}
return $arr;
}
echo print_r(findQuotients(24, 6));
echo print_r(findQuotients(24, 4));
echo print_r(findQuotients(24, 5));
Try this
$number = 24;
$divider = 6;
if($number % $divider != 0 )
{
return false;
}
$div = $number / $divider;
for($i = 1; $i <= $div; $i++)
{
echo $i*$divider;
}
The following snippet will do the trick. It's a simple loop to iterate until $num is <= 0. $num will be subtracted by the divider and each turn the next multiple of $div will be stored as a "divider step".
$num = 24;
$div = 4;
if ($num % $div != 0) {
exit('invalid');
}
$divider = array();
for ($i = 1; $num > 0; $i++) {
$divider[] = ($i * $div);
$num -= $div;
}
echo 'in: ' . $num . '<br />';
echo 'div: ' . $div . '<br />';
echo '<pre>';
print_r($divider);
exit;
based on your description you want to multiply a number and then on a given result you want to white a function:
$num = 6;
$counter = 2;
$solution = 24;
while ($num * $counter) {
$result= $num * $counter;
if ($result = $solution) {
echo $result;
// here would go your event
break;
}
}

Categories