I have an array of numbers in the codes shown below.
$result_data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$arrayCount = count($result_data);
for ($x = 0; $x < $arrayCount; $x++)
{
if ($x%5==0)
{
$sum = $result_data[0] + $result_data[1] + $result_data[2] + $result_data[3] + $result_data[4];
echo json_encode($sum);
echo ("\n");
}
}
And I got the result of:
15 15 15 15
Actually I wanted the results to be the sum of every 5 numbers in the array continuously and would expect the result to be:
15 40 65 90
Anyone knows how to get this?
You could reduce all of that code to:
$result_data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
echo implode('\n', array_map('array_sum', array_chunk($result_data, 5))),'\n';
Which outputs:
15
40
65
90
See the man pages for:
array_chunk
array_map
array_sum
implode
Instead of referecing $result_data[1], $result_data[2], $result_data[3] etc you need to base the ID off your current $x value, like this
$sum = $result_data[$x] + $result_data[$x+1] + $result_data[$x+2] + $result_data[$x+3] + $result_data[$x+4]
A different approach
I would probably approach this in a different manner, continuously adding the values as I went along, and outputting the current total when I got to each fifth number, something like this:
$result_data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$arrayCount = count($result_data);
$subtotal = 0;
for ($x = 0; $x < $arrayCount; $x++)
{
$subtotal += $result_data[$x];
if ($x%5==0)
{
echo json_encode($subtotal);
echo ("\n");
$subtotal = 0;.
}
}
try this:
$result_data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$arrayCount = count($result_data);
for ($x = 0; $x < $arrayCount; $x++)
{
if ($x%5==0)
{
$sum = $result_data[$x] + $result_data[$x+1] + $result_data[$x+2] + $result_data[$x+3] + $result_data[$x+4];
echo json_encode($sum);
echo ("\n");
}
}
Instead of
$sum = $result_data[0] + $result_data[1] + $result_data[2] + $result_data[3] + $result_data[4]
you probably wanted
$sum = $result_data[$x] + $result_data[$x+1] + $result_data[$x+2] + $result_data[$x+3] + $result_data[$x+4]
You can use:
$sum = $result_data[$x] + $result_data[$x+1] + $result_data[$x+2] + $result_data[$x+3] + $result_data[$x+4]
instead of:
$sum = $result_data[0] + $result_data[1] + $result_data[2] + $result_data[3] + $result_data[4];
since you've assigned $x inside your for loop.
Demo
Working demo
$result_data = range(1,20);
foreach($result_data as $key=>$value){
if($value%5==0){
echo $value+$result_data[$key-1]+$result_data[$key-2]
+$result_data[$key-3]+$result_data[$key-4]."\n";
}
}
Output :
15
40
65
90
Related
I want to make a series, e.g, 1/2 + 3/4 + 5/6 + 7/8 + 9/10 + 11/12 as a string using loops in php. write now i have written this code:
$output='';
for ($i=0; $i < 6; $i++)
{
$output=$output.($i+1+$i).'/'.($i+2+$i);
if ($i==5)
{
break;
}
else
{
$output=$output.'+';
}
}
echo nl2br("\n4: $output");
output:
1/2 + 3/4 + 5/6 + 7/8 + 9/10 + 11/12
is there any other better approach to do that?
preg_replace('/(\d+) \+ (\d+)/', '$1/$2', implode(" + ", range(1, 12)));
https://www.ideone.com/dKUIwc
With minimum of code it is:
$output = [];
for ($i = 0; $i < 6; $i++) {
$output[] = (2 * $i + 1) . '/' . (2 * $i + 2);
}
echo implode(' + ', $output);
Start loop from 1 and make step of 2 instead of one. Then put every sequence to array and finally implode it with +
$output = [];
for ($i = 1; $i <= 12; $i += 2) {
$output[] = $i . '/' . ($i + 1);
}
echo implode(' + ', $output);
as a string using loops in php. --> display as a string...
Use for loop and modulus operator %. Display first key, a forward slash, then continue the iteration outside that conditional and display the next key, then display a plus sign.
Continue iteration until you evaluate if the value is at the end of the array. Two conditionals inside the loop.
I used a iterator defined as $i as using a foreach loop would start at zero and you would have to do some extra code to get the last value.
$myArray = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
$stmt = NULL;
for($i = 0; $i < count($myArray); $i++){
if($myArray[$i] % 2 ){
$stmt .= $myArray[$i]."/";
}else{
if($myArray[$i] !== end($myArray)){
$stmt .= $myArray[$i].' + ';
}else{
$stmt .= $myArray[$i];
}
}
}
OUTPUT:
So i have a simple for loop to get this result from any given number (get).
1 + 2 + 3 + 4 = 10
$num = intval($_GET["number"]);
$total = 0;
for ($i = 1; $i <= $num; $i++) {
echo $i;
if ($i != $num) {
echo " + ";
}
$total += $i;
}
echo " = " . $total;
Now I want to show the calculation of every step
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
And it should be done with an Array, but I can't seem to figure out the Algorithm.
I think I'm overlooking something simple here.
Try something like this:
<?php
$num = intval($_GET["number"]);
//add all numbers to an array
$numbers = array();
for ($i = 1; $i <= $num; $i++)
{
$numbers[] = $i;
//show each array element with ' + ' in between the elements
echo implode(' + ', $numbers);
//show total sum
echo " = " . array_sum($numbers) . "\n";
}
?>
Note that this does not work, if $_GET['number'] is zero or even below zero.
Here's the simplest way I can think...
$num = intval($_GET['number']);
$intArray = range(1,$num);
echo implode(" + ",$intArray)." = ".array_sum($intArray);
You don't actually need a loop to do an arithmetic progression. An arithmetic progression like this can be calculated in constant time with the formula n * (n[-1] + n[1]) / 2.
For example the progression of 4, where n1 = 1, n2 = 2, n3 = 3, and n4 = 4 is simply 4 * (4 + 1) / 2 == 10.
function progression($n) {
return $n * ($n + 1) / 2;
}
echo progression(4); // 10
However, to show the result of the progression at any given step you simply limit the upper-bound of that progression (i.e. $n).
$n = 4;
for ($i = 1; $i <= $n; $i++) {
$operands = implode('+', range(1, $i));
echo $operands . " = " . progression($i), "\n";
}
output
1 = 1
1+2 = 3
1+2+3 = 6
1+2+3+4 = 10
Generalization
This works for any linear arithmetic progression, regardless of the upper/lower bound. So for example the progression of 5 through 8 is still 4 * (5 + 8) / 2 which gives you 26.
So you can modify this function to a more general solution for any linear arithmetic progression as such.
function progression($size, $start = 1) {
return $size * ($start + ($size + $start - 1)) / 2;
}
$n = 4;
$start = 5;
for ($i = $start; $i <= $n + $start - 1; $i++) {
$operands = implode('+', range($start, $i));
echo $operands . " = " . progression($i - $start + 1, $start), "\n";
}
output
5 = 5
5+6 = 11
5+6+7 = 18
5+6+7+8 = 26
So assuming you are doing a range from the $_GET['number'] number then you can do something like (see comments in code for further explanation):
//This will create an array from 1 to number inclusive
$nums = range(1, $_GET['number']);
//The nums that have been used
$used = array();
//Now loop over that array
foreach($nums as $num){
$used[] = $num; //Add this number to used
if(count($used) > 1){//Dont care about first loop
echo implode(' + ', $used); // put all elements together by + sign
echo ' = ' . array_sum($used) . "<br>"; //Show total plus a break
}
}
<?php
$num = intval($_GET["number"]);
$terms = [1];
for ($i = 2; $i <= $num; $i++) {
$terms[] = $i;
$sum = array_sum($terms);
echo implode(' + ', $terms) . ' = ' . $sum . PHP_EOL;
}
Going for maximum use of PHP array related functions:
$num = intval($_GET["number"]);
$array = range(1, $num);
for ($i = 2; $i <= $num; $i ++)
{
$slice = array_slice($array, 0, $i);
$total = array_sum($slice);
echo implode(" + ", $slice) . " = " . $total . PHP_EOL;
}
Alternative with array_push
$num = intval($_GET["number"]);
$array = array(1);
for ($value = 2; $value <= $num; $value ++)
{
array_push($array, $value);
echo implode(" + ", $array) . " = " . array_sum($array) . PHP_EOL;
}
Output
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
I have a N*N Matrix.Now i want to know the diagonal difference of this Matrix.What will be the best approach of this solution?
I am trying with given approach:
Such as it is 3*3 Matrix say it is:
11 15 85
66 72 21
14 21 47
the diagonal simple formula will be:
firstD= (11+72+47) = 130
secondD = (85+72+14)= 171
diagonalDiff = |firstD - secondD| = |130-171| = 41
If I count every row such as first to find out firstD (First row's first value + Sec row's Sec value + Third row's third value+..).This is my thinking.
Can anyone tell me best approaches?
Try this:
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$firstD += $arr[$i++][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);//41
Model your matrix with a multi-dimensional array and iterate through it. The easiest way should be the following:
<?
$matrix = array(array(1,2,3),array(4,5,6),array(7,8,9)); //Insert or define your matrix here..
$n = count($matrix); //Size of matrix, thanks to VolkerK
$firstD = 0;
$lastD = 0;
for($i = 0; $i < $n; $i++){
$firstD += $matrix[$i][$i];
$lastD += $matrix[$i][$n-$i-1];
}
echo $firstD."\n";
echo $lastD;
Here is a pseudo code for your problem using one simple loop:
// $array - predefined 2 dimentional array with $N rows and $N columns
$result = 0;
for ($i=0;$i<$N;$i++) {
$result += ($array[$i,$i] - &array[$i,$N-$i-1]);
}
return echo abs($result);
that way you can do the calculation in one pass, and do a diff between two elements in each row insead of calculation the sum of each diagonal
Try this:
function diagonalDifference($arr) {
$left = 0;
$right = 0;
$i = 0;
foreach($arr as $ar){
$left+= $ar[0+$i];
$right+= $ar[count($ar) - (1+$i)];
$i++;
}
return abs($left - $right);
}
Try this
$result=0;
for($i=0;$i<=count($arr)-1;$i++){
$result= $result+($arr[$i][$i])-($arr[(count($arr)-1-$i)] [$i]);
}
return abs($result);
This is the code you need:
$first = 0;
$second = 0;
for($i = 0; $i < N; $i++) {
for($j = 0; $j < N; $j++) {
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == N) {
$second += $matrix[$i][$j];
}
}
}
$diagonalDiff = abs($first - $second);
Where $matrix is a N*N array
Just using the function array_reduce:
function diagonalDifference($arr) {
$i = 0;
$n = count($arr);
return abs(array_reduce($arr,
function ($c, $str) use (&$i, $n ) {
$i++;
return $c + $str[$i-1] - $str[$n-$i];
}, 0));
}
demo
you can try this :
$first_diag=$second_diag=0;
$matrix=array(array(11,15,85),array(66,72,21),array(14,21,47));
foreach($matrix as $index=>$sub_array){
$first_diag +=$sub_array[$index];
$second_diag +=$sub_array[count($matrix)-1-$index];
}
print abs ($first_diag-$second_diag);
For one you can use a matrix library like Math_Matrix. But if this is the only operation you are gona need then it's best to write a generalized function for this using the same method you quoted yourself.
function diagonalDiff($n){
$firstD = 0;
$secondD = 0;
for($i=0;$i<$n;$i++){
for($j=0;$j<$n;$j++){
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == $n) {
$secondD += $matrix[$i][$j];
}
}
}
return abs($firstD-$secondD);
}
Should give you the answer you need for a matrix of a given size $n. (Only square Matrixes ofcourse :) )
Another better solution and it's easy to understand:
<?php
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$i++;
$firstD += $arr[$j][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);
?>
DEMO
Recently solved this question in Hacker Rank.
<?php
$m=array(array(3,4,-1,11,2),
array(-3,2,1,6,9),
array(3,4,6,5,-2),
array(1,9,9,7,-3),
array(12,9,16,7,-3));
echo count($m)."<br>";
$i=0;
$j=0;
$ek=0;
$k=0;
$n=1;
$es=count($m)-1;
for($i=0;$i<count($m);$i++)
{
for($j=0;$j<count($m);$j++)
{
echo $m[$i][$j]." ";
}
echo "<br>";
}
echo "<br>";
for($k=0;$k<count($m);$k++)
{
for($n=0;$n<count($m);$n++)
{
if($k==$n){
$ek=$ek+$m[$k][$n];
}
}
echo "<br>";
}
echo "<hr>";
$p=0;
for($k=0;$k<count($m);$k++)
{
echo $m[$k][$es-$p]."<br> ";
$p++;
}
?>
Sorry I used different variable names, I had to take this to my vs code.
$b = array(
array(1,2,5),
array(3,4,5),
array(3,4,5)
);
//So for each diag
echo $b[0][0] + $b[1][1] + $b[2][2]; //to sum the first diag
echo $b[0][2] + $b[1][1] + $b[2][0]; //to sum the second diag
//notice the pattern 00, 11, 22 vs 02,11, 20. hence why I have written the function below
function difference($b){
$d1 = 0;
$d2 = 0;
$count = count($b);
for($i=0; $i<$count; $i++){
$d1 += $b[$i][$i];
$d2 += $b[$i][$count-1-$i];
}
return abs($d1 - $d2);
}
I had the same issue, the instructions was given by the site, mislead me. However, I solved it in this way,
$n = count and store the length of input array
//define variables to store first diagonals and second diagonals
$fd = 0;
$sd = 0;
//loop through the 2D array with $i increment
$j = get an array from the main array
//in each iteration
$pd += get the values from the left to the right and add;
$sd += get the values from the right to the left and add;
}
find absolute difference between the sums using built in abs function and return it;
I think this would help someone
<?php
$numbers = array(1,2,3,4);
$total = count($numbers);
$sum = 0;
$output = "";
$i = 0;
foreach($numbers as $number) {
$i = $i + 1;
if ($i < $total) {
$sum = $sum + $number;
}
}
echo $sum;
?>
I'm going through PHP on TeamTreehouse.com, whilst learning php this was one of the quiz question, the answer is 6. I don't know why the answer is 6, can someone explain?
The variable $i is initialized by 0 (zero).
Before the condition if ($i < $total) is tested $i is incremented by 1. So even the first time it equals 1.
In the third pass $i equals 3, and in the fourth pass it equals 4 which is NOT < $total.
Therefore only 3 of the 4 elements of $numbers are summed up: 1 + 2 + 3, which equals 6.
See the comments in the code below:
<?php
$numbers = array(1,2,3,4);
$total = count($numbers); // Gives 4
$sum = 0;
$output = "";
$i = 0; // $i = 0
foreach($numbers as $number) {
$i = $i + 1; // $i = 1, even at the first time
// after 3 passes $i is equal to $total (=4)
if ($i < $total) { // So, only 3 of the 4 elements of $number are honored
$sum = $sum + $number;
}
}
echo $sum; // Thus $sum = 1 + 2 + 3 = 6
// The last element (=4) is never summed up
?>
This would sum up all 4 elements, giving 10 as the result:
foreach($numbers as $number) {
if ($i < $total) {
$sum = $sum + $number;
}
$i = $i + 1;
}
<?php
$numbers = array(1,2,3,4);
$total = count($numbers); #value of $total is 4 here
$sum = 0;
$output = ""; #intital empty
$i = 0;
foreach($numbers as $number) {
$i = $i + 1;
if ($i < $total) {
$sum = $sum + $number;
}
}
echo $sum;
?>
You increment the $i by 1 so it becomes 1 which is smaller than $total(which is 4). Your program will add till $i become 4. It just add first three number in your array.
1+2+3=6.
That's why you are getting 6.
I hope you get it. :)
The condition limits the iterations. When $i is 4 it is no longer less than $total and so the last number doesn't get added.
I have an array of numbers shown below. However, I can only calculate the standard deviation of the whole array with only output 1 result as shown below:
Codes:
function standard_deviation_sample ($a)
{
//variable and initializations
$the_standard_deviation = 0.0;
$the_variance = 0.0;
$the_mean = 0.0;
$the_array_sum = array_sum($a); //sum the elements
$number_elements = count($a); //count the number of elements
//calculate the mean
$the_mean = $the_array_sum / $number_elements;
//calculate the variance
for ($i = 0; $i < $number_elements; $i++)
{
//sum the array
$the_variance = $the_variance + ($a[$i] - $the_mean) * ($a[$i] - $the_mean);
}
$the_variance = $the_variance / ($number_elements - 1.0);
//calculate the standard deviation
$the_standard_deviation = pow( $the_variance, 0.5);
//return the variance
return $the_standard_deviation;
}
$a = array(1,2,3,4,9,6,7,8,9,20,11,12,13,14,2,16,17,18,19,27);
$standard_deviation = standard_deviation_sample ($a);
echo "standard_deviation = $standard_deviation<br>";
Results:
standard_deviation = 7.10004
Does anyone know how to compute standard deviation for every 5 numbers instead? So that the output will be:
standard_deviation_1 = 3.11448
standard_deviation_2 = 5.70088
standard_deviation_3 = 4.82701
standard_deviation_4 = 4.39318
You're looking for array_chunk(); It'll split your array up into smaller arrays of a given size, so your code would now be:
$a = array_chunk(array(1,2,3,4,9,6,7,8,9,20,11,12,13,14,2,16,17,18,19,27), 5);
foreach($a as $b){
echo "standard_deviation: " . standard_deviation_sample($b);
}
Reference: http://uk1.php.net/array_chunk
If you require the number at the end of your standard_deviation_1 output, you could change the loop to a for() loop like so:
for($i = 0; $i < count($a); $i++){
echo "standard_deviation_" . ($i + 1) . " " . standard_deviation_sample($a[$i]);
}
The answer is to use array_chunk(), but there's a few more things you can improve on the code itself:
function standard_deviation_sample(array $a)
{
$the_mean = array_sum($a) / count($a);
return sqrt(array_reduce($a, function($result, $item) use ($the_mean) {
return $result + pow($item - $the_mean, 2);
}, 0) / (count($a) - 1));
}
The function itself can be greatly reduced by only using variables where they're needed; secondly, calculating the squared standard deviation is a great example of something you can solve using array_reduce(); you start with the initial value of 0 and the inner function keeps adding the squared differences together.
$a = array(1,2,3,4,9,6,7,8,9,20,11,12,13,14,2,16,17,18,19,27);
foreach (array_chunk($a, 5) as $k => $sample) {
printf("standard_deviation_%d = %.5f<br>\n",
$k + 1,
standard_deviation_sample($sample));
}