php array negative and positive numbers - php

I have an array of values both positive and negative:
$numbers=['10','-2','-1','8','-7','1','-2','-3'];
I need to echo the results as:
numbers[0]=10;
numbers[1]=8;
numbers[2]=7;
numbers[3]=8;
numbers[4]=1;
numbers[5]=1;
numbers[6]=-1;
numbers[7]=-4;
Basically I take the first value that is always positive, echo that value, subtract the first negative value, echo the results, the second, etc until I found the next positive value, I echo that value, subtract from this value that becomes now reference the second negative value and so on...
I tries this in a loop but I can't manage to "break" the results after finding the second positive number - the numbers keep adding at the result from the first set of positive + negative values - even when using unset....
$i=0;
$sum=0;
while ($i < count($numbers)){
$sum=$sum+$numbers[i];
if($numbers[i]>0)
{
echo $numbers[i];
}
else
{
echo $sum;
}
}

You need to reset $sum to the number whenever you get a positive number.
foreach ($numbers as $i => $num) {
if ($num > 0) {
$sum = $num;
} else {
$sum += $num;
}
echo "numbers[$i] = $sum<br>";
}

$numbers=['10','-2','-1','8','-7','1','-2','-3'];
$i=0;
// there is no need initializing sum here since you it will be the first number
$sum=0;
while ($i < count($numbers)){
// $sum=$sum+$numbers[$i]; This is not needed
if ($numbers[$i] > 0) {
// if the $numbers[$i] is greater than 0 then it is a positive number
// you set $sum to the new positive number
$sum = $numbers[$i];
} else {
//else you perform arithmetic function here
// and since $numbers[$i] is a negetive number adding it will substract from $sum
$sum += $numbers[$i];
}
// You're concern about the sum so you should do your logic before echoing
echo $sum;
// Always remember to increment as while loop wont do that for you
$i++;
}

Related

find first occurence of a sum of digits in an endless number

For an endless number such as Pi, how would one go about finding the first occurrence of an exact sum of digits for a given number n.
For example. If n=20
Pi=3.14159265358979323846264338327950288419716939...
then the first occurrence is from digit 1 to digit 5 since:
1+4+1+5+9=20
if n=30, then the first occurrence is from digit 5 to digit 11
since 9+2+6+5+3+5=30
answer should have a working php demo
The answer to this is using sliding window that will maintain the sum. so maintain two pointers say i and j. Keep increasing j and adding the elements inside. when it crosses the desired sum increase i and decrease the element at i. Then keep increasing j until the sum is reached or the sum overflows so you repeat the above process.
Example sum = 30
141592653589793238 >> i=j=0 current_sum = 1
141592653589793238 >> i=0 j=6 current_sum=28
in the next iteration adding 5 will result in current_sum>30 so hence you increment i
141592653589793238 >> i=1 j=6 current_sum=27
141592653589793238 >> i=2 j=6 current_sum=23
141592653589793238 >> i=2 j=7 current_sum=28
Keep going in this manner and it will finally reach the window that is equal to the sum =30 . That should break you out of the loop and help you find the answer.
Method 1 (suggested by Ashwin Bhat)
This implementation uses two pivots. The sum of digits between $pivot_a and $pivot_b is computed. Depending on the value of the sum, we increment $pivot_b (if the sum is less) or $pivot_a (if the sum is greater). If the sum is equal to $n, break. The values of the pivots give the appropriate digit indices.
$pi = "314159265358979323846264338327950288419716939";
$n = 30;
$pivot_a = $pivot_b = 0;
$sum = 0;
for( ; $pivot_b < strlen($pi); ) {
if($sum < $n) {
$sum += $pi[$pivot_b++];
} elseif ($sum > $n) {
$sum -= $pi[$pivot_a++];
} else {
print('Solution found from digit '.$pivot_a.' to '.$pivot_b.'.');
exit;
}
}
print('No match was found.');
Method 2
This implementation uses one pivot only, from which it starts summing up the digits. If the sum happens to be greater than the desired value, it resets the sum to zero, shifts the pivot one position and starts the summing again.
$pi = "314159265358979323846264338327950288419716939";
$n = 30;
// Let's sum up all the elements from $pivot until we get the exact sum or a
// number greater than that. In the latter case, shift the $pivot one place.
$pivot = 0;
$sum = 0;
for($k=0 ; $sum != $n && $k < strlen($pi) ; $k++) {
$sum += $pi[$k];
print($pi[$k]);
if($sum > $n) {
print(' = '.$sum.' fail, k='.($pivot+1).PHP_EOL);
$sum = 0;
$k = $pivot++;
} elseif($sum < $n) {
print("+");
}
}
print(' = '.$n.' found from digit '.$pivot.' to '.$k.'.');
The implementation is not very effective but tries to explain the steps. It prints
3+1+4+1+5+9+2+6 = 31 fail, k=1
1+4+1+5+9+2+6+5 = 33 fail, k=2
4+1+5+9+2+6+5 = 32 fail, k=3
1+5+9+2+6+5+3 = 31 fail, k=4
5+9+2+6+5+3 = 30 found from digit 4 to 10.
Here's another approach. It builds an array of sums along the way and, on every iteration, attempts to add the current digit to the previous sums, and so on, while always only keeping the sums that are still relevant (< target).
The function either returns:
an array of 2 values representing the 0-based index interval within the digits,
or null if it couldn't find the target sum
Code:
function findFirstSumOccurrenceIndexes(string $digits, int $targetSum): ?array
{
$sums = [];
for ($pos = 0, $length = strlen($digits); $pos < $length; $pos++) {
$digit = (int)$digits[$pos];
if ($digit === $targetSum) {
return [$pos, $pos];
}
foreach ($sums as $startPos => $sum) {
if ($sum + $digit === $targetSum) {
return [$startPos, $pos];
}
if ($sum + $digit < $targetSum) {
$sums[$startPos] += $digit;
}
else {
unset($sums[$startPos]);
}
}
$sums[] = $digit;
}
return null;
}
Demo: https://3v4l.org/9t3vf

PHP for loop, breaking

I'm trying to have the loop stop before it reaches the designated number of repeats if the value being calculated is equal to another variable. I have a break in an if statement but it doesn't seem to do anything as it just continues to loop until it reaches the designated end value.
echo "<h4>iteration Stages</h4>\n";
// looping the math for each iteration
for ($i=1; $i <= $iterations ; $i++) {
$estimate = 0.5 * ($estimate + $number / $estimate);
if ($estimate == $real){
echo round($estimate, 2);
break;
} else {
echo round($estimate, 2);
echo " -- \n";
}
}

Multiple counters not counting ( foreach / ifs)

This is my first StackOverFlow post.
I have an array of numbers, which I shuffle:
$nums = array("1","1","1","1","1","2","2","2","2","3","3","3","4","4","4");
shuffle($nums);
I am trying to identify a sequence/pattern of any three 3 identical numbers in a row in the shuffled array and
output the combined total of all sets of matching numbers.
The problem that I am running into seems to stem from attempting to compare the current number in the loop with the previous number (to see if they match).
When I echo the "previous" number it always outputs as "0". Thus I am unable to compare the current number and old number, which means I am not able to sum identify and sum a pattern of identical numbers.
Here is my code:
<?php
$t3count = 0;
$oldnum = 0;
$tots = 0;
$nums = array("1","1","1","1","1","2","2","2","2","3","3","3","4","4","4");
shuffle($nums);
foreach ($nums as $num) {
echo "$num: [$oldnum] ";
if ($num = $oldnum) {
$t3count++;
if ($t3count = 3) {
$tots = $num * $num;
$t3count = 0;
$oldnum = $num;
} else {
# do nonum
}
}
else {
$oldnum = $num;
}
# echo "<li>$num</li>";
}
echo "Your total is: $tots";
unset($num);
?>
Thank you.
You need to do comparison == not assignment = here:
if ($num = $oldnum)
and here:
if ($t3count = 3)
also this is probably going to bite you if i got the logic right
$t3count++;
if ($t3count == 3) {
how do you know which one counted to 3, id build nested arrays of like values first then process that.
you missed == to compare if ($num = $oldnum) and if ($t3count = 3)
replace with
if ($num == $oldnum)
if ($t3count == 3)

find max sum in array

I have a working solution for my problem but now I want to improve it.
Consider the array
3,4,5,9,1,2,8
I need to find the max difference between two elements at position i and j such that i < j that is I want to find max difference between two elements where the 2nd element comes after 1st element.
In the input I gave the answer is 7 because 8-1 = 7 and 8 is after 1.
The program works but when I have a very large array it takes lot of time. Can we improve on it?
function fMax($arr)
{
$sum = $arr[1] - $arr[0];
for($i=0;$i<count($arr);$i++)
{
for($j=$i+1;$j<count($arr);$j++)
{
if($sum < $arr[$j] - $arr[$i])
{
$sum = $arr[$j] - $arr[$i];
}
}
}
return $sum;
}
Thanks a lot to all the answers. I have used the code by codeaddict and it works fast.
Your current approach is O(N^2) you can improve it to O(N).
You are comparing each element with every other element. Instead you can keep track of the max difference and min element seen so far.
So every time you test a new element you see
if its difference with the current
min will give a better max sum if so
update the max sum and
if that number is less than the min
so far you update the min.
PHP function:
function ImprovedFindMax($arr) {
// initial max sum.
$sum = $arr[1] - $arr[0];
// initial min.
$min = $arr[0];
// iterate for every other ele starting from 2nd.
for($i=1;$i<count($arr);$i++) {
// if this ele give larger sum then update sum.
if($arr[$i] - $min > $sum) {
$sum = $arr[$i] - $min;
}
// if this ele is smaller than min..update min.
if($arr[$i] < $min) {
$min = $arr[$i];
}
}
// return $sum which will be the max sum.
return $sum;
}
Ideone Link
One iteration, track the minimum and the maxdiff. At each element, if the value is less than the minimum, set the minimum to the value; else, if the value - minimum is greater than maxdiff, set the maxdiff to that difference. Turns it from an O(n^2) to O(n).
This should work. I haven't tested it.
$arr = array(3,4,5,9,1,2,8);
$min = PHP_INT_MAX;
$maxdiff = 0;
foreach($arr as $i) {
if ($i < $min) {
$min = $i;
}
if ($maxdiff < $i - $min) {
$maxdiff = $i - $min;
}
}
echo "maxdiff: {$maxdiff}\n";

Get the sum of all digits in a numeric string

How do I find the sum of all the digits in a number in PHP?
array_sum(str_split($number));
This assumes the number is positive (or, more accurately, that the conversion of $number into a string generates only digits).
Artefactos method is obviously unbeatable, but here an version how one could do it "manually":
$number = 1234567890;
$sum = 0;
do {
$sum += $number % 10;
}
while ($number = (int) ($number / 10));
This is actually faster than Artefactos method (at least for 1234567890), because it saves two function calls.
Another way, not so fast, not single line simple
<?php
$n = 123;
$nstr = $n . "";
$sum = 0;
for ($i = 0; $i < strlen($nstr); ++$i)
{
$sum += $nstr[$i];
}
echo $sum;
?>
It also assumes the number is positive.
function addDigits($num) {
if ($num % 9 == 0 && $num > 0) {
return 9;
} else {
return $num % 9;
}
}
only O(n)
at LeetCode submit result:
Runtime: 4 ms, faster than 92.86% of PHP online submissions for Add Digits.
Memory Usage: 14.3 MB, less than 100.00% of PHP online submissions for Add Digits.
<?php
// PHP program to calculate the sum of digits
function sum($num) {
$sum = 0;
for ($i = 0; $i < strlen($num); $i++){
$sum += $num[$i];
}
return $sum;
}
// Driver Code
$num = "925";
echo sum($num);
?>
Result will be 9+2+5 = 16
Try the following code:
<?php
$num = 525;
$sum = 0;
while ($num > 0)
{
$sum= $sum + ($num % 10);
$num= $num / 10;
}
echo "Summation=" . $sum;
?>
If interested with regex:
array_sum(preg_split("//", $number));
<?php
echo"----Sum of digit using php----";
echo"<br/ >";
$num=98765;
$sum=0;
$rem=0;
for($i=0;$i<=$num;$i++)
{
$rem=$num%10;
$sum=$sum+$rem;
$num=$num/10;
}
echo "The sum of digit 98765 is ".$sum;
?>
-----------------Output-------------
----Sum of digit using php----
The sum of digit 98765 is 35
// math before code
// base of digit sums is 9
// the product of all numbers multiplied by 9 equals 9 as digit sum
$nr = 58821.5712; // any number
// Initiallization
$d = array();
$d = explode(".",$nr); // cut decimal digits
$fl = strlen($d[1]); // count decimal digits
$pow = pow(10 ,$fl); // power up for integer
$nr = $nr * $pow; // make float become integer
// The Code
$ds = $nr % 9; // modulo of 9
if($ds == 0) $ds=9; // cancel out zeros
echo $ds;
Assume you want to find the sum of the digits of a number say 2395 the simplest solution would be to first split the digits and find out the sum then concatenate all the numbers into one single number.
<?php
$number=2;
$number1=3;
$number2=9;
$number3=5;
$combine=$number.$number1.$number2.$number3;
$sum=$number+$number1+$number2+$number3;
echo "The sum of $combine is $sum";
?>
One way of getting sum of digit however this is a slowest route.
$n=123;
while(($n=$n-9)>9);
echo "n: $n";
<html>
<head>
<title>detail</title>
</head>
<body>
<?php
$n = 123;
$sum=0; $n1=0;
for ($i =0; $i<=strlen($n);$i++)
{
$n1=$n%10;
$sum += $n1;
$n=$n/10;
}
echo $sum;
?>
</body>
</html>
Here's the code.. Please try this
<?php
$d=0;
$num=12345;
$temp=$num;
$sum=0;
while($temp>1)
{
$temp=$temp/10;
$d++;
}
echo "Digits Are : $d </br>";
for (;$num>1;)
{
$d=$num%10;
$num=$num/10;
$sum=$sum+$d;
}
echo "Sum of Digits is : $sum";
?>

Categories