How to calculate the average progressively without know the total items? - php

(Language PHP - This question is for any language, particularly I'm using PHP)
For example you have an array of numbers like:
$q = array( 1, 2, 3, 4, 5, ... ); // ... mean you can give more numbers
$i = 0;
$currentAverage = 0;
while ($i < count( $q )) {
$currentAverage = ($currentAverage + $q[$i]) / 2; // this is my try
$i++;
}
echo "The final average is: " . $currentAverage . "<br/>";
Obviusly, you can divide by count( $q ) the sum, but that's not the idea.
I hope you can help me! thanks.

You can't calculate an "incremental" mean average without knowing the total number of items make up that average.
For example, if you have 10 items that average 5 and you want to add the next item, X, you have to give the appropriate "weight" to the newly added item.
For example, to get the next average, you would do
(currentAverage * currentNumberOfItems + X) / (currentNumberOfItems + 1)
If we say X is 7, the new average would be
(5 * 10 + 7) / (10 + 1)
= (50 + 7) / 11
= 57 / 11
= 5.181818182
It is impossible to do this calculation without knowing the current number of items that make up the average (10) beforehand
To show you this working in an incremental fashion, here is a for loop that keeps track of the average as the loop is running
$xs = [1,2,3,4,5];
$average = $xs[0];
for ($count = 1; $count < count($xs); $count++) {
echo sprintf("average: %0.3f, count: %d" . PHP_EOL, $average, $count);
$average = ($average * $count + $xs[$count]) / ($count + 1);
}
average: 1.000, count: 1
average: 1.500, count: 2
average: 2.000, count: 3
average: 2.500, count: 4

Could use this:
$q = array( 1, 2, 3, 4, 5, ... ); // ... mean you can give more numbers
$i = 0;
$currentAverage = 0;
while ($i < count( $q )) {
$sliceArr = array_slice($q, 0, $i+1);
$currentAverage = array_sum($sliceArr) / count($sliceArr);
$i++;
}
echo "The final average is: " . $currentAverage . "<br/>";

Related

PHP Making a variable increment based on another variable's value without having too much code?

i'm trying to increase a variable value depending on the other variable value for example:
i have a variable called $totalhousesleft...
i want to set a price depending on how many $totalhousesleft i have...
everytime the totalhousesleft is down by 10, i want to increase the variable $currentprice by 1.
the starting value of $totalhouses left is 8000 and every time it goes down by 10, i set the $currentprice +1... the starting value of current price is 9...
something like:
If ($totalhousesleft >= 8000) {$currentprice = 9; $sellingprice = 8;}
If ($totalhousesleft >= 7990) {$currentprice = 10; $sellingprice = 9;}
If ($totalhousesleft >= 7980) {$currentprice = 11; $sellingprice = 10;}
If ($totalhousesleft >= 7970) {$currentprice = 12; $sellingprice = 11;}
ALL THE WAY DOWN UNTIL HOUSES LEFT IS 1. If someone can please show me a loop or a shorter code i would really appreciate it!
#elias-soares answer is close, but is missing ceil...and an explanation.
foreach ( [8000, 7995, 7990, 7985, 7980, 7975, 7970, 7965] as $totalhousesleft ) {
$currentprice = 9 + ((ceil(800 - ((min(8000, $totalhousesleft)) / 10))) * 1);
$sellingprice = $currentprice - 1;
}
Try it here: https://onlinephp.io/c/68196
Let's break down how to get $currentprice:
//$currentprice = ceil(9 + (800 - (min(8000, $totalhousesleft) / 10)));
// get the lesser of 8000, or $totalhousesleft
// in other words, 8000 is the maximum number to calculate
$totalhousesleft = min(8000, $totalhousesleft);
// divide total houses left into number of tenth units
$tenth = $totalhousesleft / 10;
// since the price increases when the number of tenth units decreases,
// the unit factor is the difference between the max possible tenths
// and tenths of the current total houses left
$tenthunit = 800 - $tenth;
// tenth unit is fractional for values not evenly divisible by 10,
// so round up
$tenthroundup = ceil($tenthunit);
// multiply the number of tenth units with the price per unit
$pricepertenth = $tenthroundup * 1; // 1 currency per tenth unit
// add the price per tenth cost to the base cost (9 currency)
$currentprice = 9 + $pricepertenth;
Bonus: this can be implemented in a function:
function getPrices ($totalhousesleft, $baseprice = 9, $discount = 1, $priceperunit = 1, $maxtotal = 8000, $units = 10) {
$currentprice = $baseprice + ((ceil(($maxtotal / $units) - ((min($maxtotal, $totalhousesleft)) / $units))) * $priceperunit);
return [$currentprice, $currentprice - $discount];
}
foreach ( [8000, 7995, 7990, 7985, 7980, 7975, 7970, 7965] as $totalhousesleft ) {
list($currentprice, $sellingprice) = getPrices($totalhousesleft);
}
Try it here: https://onlinephp.io/c/2672b
A for or while loop could be used for this. I'd use for:
$iteration = 0;
for($x = 8000; $x > 0; $x = $x - 10){
if(empty($iteration)) {
$iteration = $x/1000;
}
if ($totalhousesleft >= $x) {
$currentprice = $iteration;
$sellingprice = $currentprice + 1;
break;
}
$iteration++;
}
if(empty($currentprice)){
$currentprice = $iteration;
$sellingprice = $currentprice + 1;
}
This iterates over until a match is found then breaks out of the looping. The prices are based on the iteration it is in.
Demo link: https://3v4l.org/Mm432 (updated for edge cases 0-9)
You can use Math.
$currentprice = 9 + (800 - (min(8000,$totalhousesleft)/10));
$sellingprice = $currentprice - 1;

Prefix sum find max collect value by moving in array in m moves

I am trying to implement the prefix sum logic in php codility.
Here is the problem that I'm trying to solve:
You are given a non-empty, zero-indexed array A of n (1 ¬ n ¬ 100 000)
integers a0, a1, . . . , an−1 (0 ¬ ai ¬ 1 000). This array represents
number of mushrooms growing on the consecutive spots along a road. You
are also given integers k and m (0 ¬ k, m < n). A mushroom picker is
at spot number k on the road and should perform m moves. In one move
she moves to an adjacent spot. She collects all the mushrooms growing
on spots she visits. The goal is to calculate the maximum number of
mushrooms that the mushroom picker can collect in m moves. For
example, consider array A such that: [2, 3, 7, 5, 1, 3, 9]
The mushroom picker starts at spot k = 4 and should perform m = 6
moves. She might move to spots 3, 2, 3, 4, 5, 6 and thereby collect 1
+ 5 + 7 + 3 + 9 = 25 mushrooms. This is the maximal number of mushrooms she can collect.
Here's my code in php:
$P = [2, 3, 7, 5, 1, 3, 9]; // mushroom count per position
$k = 4; // start position of picker
$m = 6; // moves allowed
$n = count($P);
$result = 0;
$pref = $this->getPrefixSum($P);
$leftBoundary = min($m, $k);
for ($i=0; $i < $leftBoundary; $i++) {
$leftPos = $k - $i;
$rightPos = min($n - 1, max($k, $k + $m - 2 * $i));
$result = max($result, $pref[$rightPos] - $pref[$leftPos]);
}
$rightBoundary = min($m + 1, $n - $k);
for ($i=0; $i < $rightBoundary ; $i++) {
$rightPos = $k + $i;
$leftPos = max(0, min($k, $k - ($m - 2 * $i)));
$result = max($result, $pref[$rightPos] - $pref[$leftPos]);
}
function getPrefixSum($A)
{
$prefixSums = array();
$prefixSums[0] = $A[0];
for ($i=1; $i < count($A); $i++) {
$prefixSums[$i] = $prefixSums[$i - 1] + $A[$i];
}
return $prefixSums;
}
Unfortunately, I am getting a result of 19 only (Expected answer was 25). Do you guys have any idea if I'm missing anything? Any help would be appreciated.
There are multiple mistakes translating the code from the example. The primary problem is that your prefixSum function is producing an array with one less index than the example code. Here's a comparison:
# them
[0, 2, 5, 12, 17, 18, 21, 30]
# you
Array
(
[0] => 2
[1] => 5
[2] => 12
[3] => 17
[4] => 18
[5] => 21
[6] => 30
)
Otherwise, you've omitted operations that they included, so I'll highlight them in the working code below:
function getPrefixSum($A) {
$prefixSums = [0];
# ^^^
for ($i = 1; $i < count($A) + 1; $i++) {
# ^^^^
$prefixSums[$i] = $prefixSums[$i-1] + $A[$i-1];
# ^^
}
return $prefixSums;
}
$P = [2, 3, 7, 5, 1, 3, 9]; // mushroom count per position
$k = 4; // start position of picker
$m = 6; // moves allowed
$n = count($P);
$result = 0;
$pref = getPrefixSum($P);
$leftBoundary = min($m, $k) + 1;
# ^^^^
for ($i = 0; $i < $leftBoundary; $i++) {
$leftPos = $k - $i;
$rightPos = min($n - 1, max($k, $k + $m - 2 * $i));
$result = max($result, $pref[$rightPos+1] - $pref[$leftPos]);
# ^^
}
$rightBoundary = min($m + 1, $n - $k);
for ($i = 0; $i < $rightBoundary; $i++) {
$rightPos = $k + $i;
$leftPos = max(0, min($k, $k - ($m - 2 * $i)));
$result = max($result, $pref[$rightPos+1] - $pref[$leftPos]);
# ^^
}
echo "$result\n";
Output:
25
Try it out.

random logic to print numbers in following pattern

Currently, I have an array r[1] to r[12].
Now, I need to print it like this:
r[10] r[11] r[12]
r[7] r[8] r[9]
r[4] r[5] r[6]
r[1] r[2] r[3]
for (int i = 0; i < 4; i++){
for(int j = 0; j < 3; j++){
print("%d", r[ 12 - (i * 3) + j]);
}
}
If you need any other numbers than you could generalize the solution
for (int i = 0; i < count / interval; i++){
for(int j = 0; j < interval; j++){
print("%d", r[ count - (i * interval) + j]);
}
supposing you've got an array with n elements and you want to show them in row of 3 elements, you could proceed in this way (in php):
// this is your array, it starts with 1 and could end with n (but it must be divisible by 3)
$array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
// check if the number of the elements is ok for the script
if (count($array) % 3) {
echo "The array must be divisible for the number of the element in a row!";
exit;
}
// for each row, from 1 to number of the elements in array...
for ($row = 1; $row <= count($array) / 3; $row++){
// ... and for each column (with a max of 3 columns)
for($column = 0; $column < 3; $column++){
// print out the last element, less current row multipled by 3 plus the number of the column (which was started with 1).
echo $array[count($array) - ($row * 3) + $column] . " ";
}
// another row is finished, move the cursor to the next line
echo "<br />";
}

How can I find how often the sum of three consecutive values in a set equal a certain value?

9 numbers. Count how often the sum of 3 consecutive numbers in this set of numbers equaled to 16:
2, 7, 7, 1, 8, 2, 7, 8, 7,
The answer is 2. 2 + 7 + 7 = 16 and 7 + 1 + 8 = 16
But I can't seem to get the answer, because I don't know how to "loop" back and skip the first number and do the process over.
How would one be able to solve this utilizing arrays, and how would one solve this without utilizing arrays?
The 9 numbers are randomly generated, and it has to stay that way, but for the sake of solving, I used seed of 3 using srand(3). This is my current code below:
<?php
srand(3);
$count = 1;
$answer = 0;
$num1 = 0;
$num2 = 0;
$num3 = 0;
for ($i = 0; $i < 9; $i++)
{
$num = rand(0, 9);
echo $num . ', ';
if ($count == 1)
$num1 = $num;
else if ($count == 2)
$num2 = $num;
else if ($count == 3)
{
$num3 = $num;
$count = 1;
}
if ($num1 + $num2 + $num3 == 16)
$answer++;
$count++;
}
echo '<br />*******' . $answer . '*******';
?>
Obviously this isn't the right answer because I had to do the check again, but skipping the first number, and so on and so forth until (the last indexed number - index 3)
Probably not the most efficient solution, but its hard to think at 11 at night:
$array = array(2, 7, 7, 1, 8, 2, 7, 8, 7);
$count = count($array);
for ($x = 0; $x < $count; $x++) {
$parts = array_chunk($array, 3);
foreach ($parts as $part) {
if (array_sum($part) == 16 && count($part) == 3) {
print_r($part);
}
}
array_shift($array);
}
Another solution which I think is the more efficient, logic similar to what #Jeroen Vannevel answered:
$array = array(2, 7, 7, 1, 8, 2, 7, 8, 7);
$count = count($array) - 2;
for ($x = 0; $x < $count; $x++) {
if ($array[$x] + $array[$x+1] + $array[$x+2] == 16) {
echo "{$array[$x]} + {$array[$x+1]} + {$array[$x+2]} = 16 <br />";
}
}
Not a PHP writer but this could be your approach:
Fill the array from indices 0 up to and including 8 with a random value.
Iterate from index 0 to index [length - 3]. (length is 9)
Calculate the sum of the values on index [currentIndex], [currentIndex + 1] and [currentIndex + 2].
Whenever the value of that sum equals 16, increment your [count] variable by 1.

How to display each number of a variable?

basically what I want is display a count until it reaches a certain number, so if I had the number "5" on the screen it would show "1 2 3 4 5". Or if I had the number "3" it would show "1 2 3".
The reason is because im creating a paging system for my MySQL results. The code I have so far is
$result1 = mysql_query("SELECT * FROM questions WHERE subcat = '$conditions'");
$num_rows = mysql_num_rows($result1);
$results_per_page = "3";
$num_pages = $num_rows / $results_per_page;
So it counts how many results there are, for example we will say 12 results. It then devides this number by how many results I want shown per page. In this example its "3". So the answer is "4".
So I now want to have "1 2 3 4" displayed on the screen, however I want each number to be a link.
How do I do this?
Thanks
Ben
foreach( range( 1, $num_pages) as $i) {
echo '' . $i . '';
}
Or, an approach suggested by knittl:
echo implode( ' | ', array_map( function( $i) {
return sprintf( '%d', $i, $i);
}, range( 1, $num_pages)));
Prints something like this:
1 | 2 | 3 | 4 | 5
Use a for loop.
for($i = 1; $i <= $num_pages; $i++){
echo ''.$i.' ';
}
Use a loop:
for($i = 0; $i < $num_pages; ++$i) {
printf('page %d', $i, $i);
}

Categories