Default php function that turns negative numbers in 0 - php

Is there such a thing?
for eg
$var = -5;
echo thefunction($var); // should be 0
$var = 5;
echo thefunction($var); // should be 5

Try max($var,0), which will have the desired effect. See the manual page for more information.

Not built-in but, here you have:
function thefunction($var){
return ($var < 0 ? 0 : $var);
}
Hope this helps

In PHP, checking if a integer is negative and if it is then setting it to zero is easy, but I was looking for something shorter (and potentially faster) than:
if ($x < 0) $x = 0;
Well, this is a very quick check and reset, but there is a function max that does this too and it works with arrays too.
$x = max(0, $x); // $x will be set to 0 if it was less than 0
The max() function returns the number with the highest value of two specified numbers.
echo max(1, 3, 5, 6, 7); // 7
echo max(array(2, 4, 5)); // 5
echo max(0, 'hello'); // 0
echo max('hello', 0); // hello
echo max(-1, 'hello'); // hello
// With multiple arrays, max compares from left to right
// so in our example: 2 == 2, but 4 < 5
$val = max(array(2, 4, 8), array(2, 5, 7)); // array(2, 5, 7)
// If both an array and non-array are given, the array
// is always returned as it's seen as the largest
$val = max('string', array(2, 5, 7), 42); // array(2, 5, 7)

function thefunction($number){
if ($number < 0)
return 0;
return $number;
}
that should do the trick

Simply:
echo $var < 0 ? 0 : $var;

Related

How to efficiently sum paired array elements and avoid offset errors in case of pairless array?

Pair every two arrays is the task – store it, print it and repeat it until it becomes one value.
input : 1, 2, 3, 4, 5, 6, 8, 9, 9
output: 3 7 11 17 9
10 28 9
38 9
47
My code is working fine in this scenario. Somehow I managed to add 0 at the end for pairless elements. But my main focus is how can I make the logic even more clearer to avoid grumpy offset errors?.
My code:
function sumForTwos($arr)
{
if(count($arr) == 1){
exit;
}
else {
$sum = [];
for ($i = 0; $i < count($arr) -1; $i++)
{
//logic to add last array for odd count to avoid offset error
if(count($arr) % 2 == 1){ $arr[count($arr)] = 0; }
//logic to pair arrays
if($i != 0) { $i++; }
$sum = $arr[$i] + $arr[$i + 1];
$total[] = $sum;
echo $sum . " ";
}
echo "<br>";
$arr = $total;
//Recursion function
sumForTwos($arr);
}
}
sumForTwos([1, 2, 3, 4, 5, 6, 8, 9, 9]);
You can adopt an iterative approach and look at this as processing each level of values with every next level have 1 value less from total values. In other words, you can look at this as a breadth first search going level by level. Hence, you can use a queue data structure processing each level one at a time.
You can use PHP's SplQueue class to implement this. Note that we can advantage of this class as it acts as a double-ended queue with the help of below 4 operations:
enqueue - Enqueues value at the end of the queue.
dequeue - Dequeues value from the top of the queue.
push - Pushes value at the end of the doubly linked list(here, queue is implemented as doubly linked list).
pop - Pops a node from the end of the doubly linked list.
Most certainly, all the above 4 operations can be done in O(1) time.
Algorithm:
Add all array elements to queue.
We will loop till the queue size is greater than 1.
Now, if queue level size is odd, pop the last one and keep it in buffer(in a variable).
Add all pairwise elements by dequeueing 2 at a time and enqueue their addition for next level.
After level iteration, add the last element back if the previous level size was odd.
Print those added elements and echo new lines for each level accordingly.
Snippet:
<?php
function sumForTwos($arr){
if(count($arr) == 1){
echo $arr[0];
return;
}
$queue = new SplQueue();
foreach($arr as $val){
$queue->enqueue($val); // add elements to queue
}
while($queue->count() > 1){
$size = $queue->count();
$last = false;
if($size % 2 == 1){
$last = $queue->pop(); // pop the last odd element from the queue to make queue size even
$size--;
}
for($i = 0; $i < $size; $i += 2){
$first = $queue->dequeue();
$second = $queue->dequeue();
echo $first + $second," ";
$queue->enqueue($first + $second);
}
if($last !== false){// again add the last odd one out element if it exists
echo $last; // echo it too
$queue->push($last);
}
echo PHP_EOL;// new line
}
}
sumForTwos([1, 2, 3, 4, 5, 6, 8, 9, 9]);
Demo: http://sandbox.onlinephpfunctions.com/code/5b9f6d4c9291693ac7cf204af42d1f0ed852bdf9
Does this do what you want?
function pairBySums($inputArray)
{
if (sizeof($inputArray) % 2 == 1) {
$lastEntry = array_pop($inputArray); //$inputArray now has even number of elements
}
$answer = [];
for ($ii = 0; $ii < sizeof($inputArray) / 2; $ii++) {
$firstIndexOfPair = $ii * 2; // 0 maps to 0, 1 maps to 2, 3 maps to 4 etc
$secondIndexOfPair = $firstIndexOfPair + 1; // 0 maps to 1, 1 maps to 3, 2 maps to 5 etc
$answer[$ii] = $inputArray[$firstIndexOfPair] + $inputArray[$secondIndexOfPair];
}
if (isset($lastEntry)) {
array_push($answer, $lastEntry);
}
echo implode(' ', $answer) . "<br>";
if (sizeof($answer) > 1) {
pairBySums($answer);
}
}
The algorithm makes sure it operates on an even array and then appends the odd entry back on the array if there is one.
$input = [1, 2, 3, 4, 5, 6, 8, 9, 9];
pairBySums($input);
produces:
3 7 11 17 9
10 28 9
38 9
47
With an even number of items,
$input = [1, 2, 3, 4, 5, 6, 8, 9];
pairBySums($input);
produces:
3 7 11 17
10 28
38

Return the smallest positive integer

function solution($A);
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−1,000,000..1,000,000].
Below is my attempt:
function solution($A) {
// write your code in PHP7.0
$n=1;
while($n > 0 && $n <= 1000000)
$n ++;
echo $A=$n+1;
}
echo solution;
?>```
Try this, no loop required:
<?php
function solution($set) {
$diff = array_diff(range(1, max($set)), $set);
sort($diff);
return !isset($diff[0]) ? max($set) + 1 : ($diff[0] < 1 ? 1 : $diff[0]);
}
echo solution([39, 68, 47, 2, 19, 64]); // 1
echo solution([1, 3, 6, 4, 1, 2]); // 5
echo solution([1, 2, 3]); // 4
echo solution([-1, -3]); // 1
https://3v4l.org/h28LZ
Here's a one-liner to either impress your professor or get kicked out of the class for not following instructions:
php > function solution(array $A) { return max(array(1,min(array_diff(range(1,100000),$A)))); }
php > echo solution([39, 68, 47, 2, 19, 64]);
1
php > echo solution([1,3,6,4,1,2]);
5
php > echo solution([-1,-3]);
1
php > echo solution([1,2,3]);
4
It generates array N (1-1,000,000) and runs array_diff against your input A, and returns either the lowest result from that comparison or 1 if it's less than or equal to 0.
function solution($A) {
$smallest = 1;
while(in_array($smallest, $A)){
$smallest++;
}
return $smallest;
}
Above is the smallest code but has O(N^2) Complexity with 66% success
function solution($A) {
$flipped = array_flip($A);
$smallest = 1;
while (isset($flipped[$smallest])){
$smallest++;
}
return $smallest;
}
Detected time complexity:
O(N) or O(N * log(N)) with 100% success rate

PHP array slice from position + attempt to return fixed number of items

I'm looking for an efficient function to achieve the following. Let's say we have an array:
$a = [0, 1, 2, 3, 4, 5, 6, 7];
Slicing from a position should always return 5 values. 2 before the position index and 2 values after the position index - and of course, the position index itself.
If a position index is at the beginning of the array i.e. 0 (example 2), the function should return the next 4 values. Similarly, if the position index is at the end of the array (example 3), the function should return the previous 4 values.
Here's some examples of various indexes one could pass to the function and expected results:
$index = 3; // Result: 1, 2, 3, 4, 5. *example 1
$index = 0; // Result: 0, 1, 2, 3, 4. *example 2
$index = 7; // Result: 3, 4, 5, 6, 7. *example 3
$index = 6; // Result: 3, 4, 5, 6, 7. *example 4
As represented in examples: (example 1, example 4), the function should always attempt to catch tokens succeeding and preceding the position index - where it can, whilst always returning a total of 5 values.
The function must be bulletproof to smaller arrays: i.e if $a has 4 values, instead of 5, the function should just return everything.
Something like this?
#edit:
Sorry, I misread your original requirement. Second attempt:
function get_slice_of_5($index, $a) {
if ($index+2 >= count($a)) {
return array_slice($a, -5, 5)
}
else if($index-2 <= 0) {
return array_slice($a, 0, 5)
}
else return array_slice($a, $index-2, 5)
}
Create a start position by calculating where to start and use implode and array slice to return the string.
$a = [0, 1, 2, 3, 4, 5, 6, 7];
$index = 3; // Result: 1, 2, 3, 4, 5. *example 1
echo pages($a, $index) . "\n";
function pages($a, $index){
if($index >= count($a)-2){
$start = count($a)-5; // index is at end of array
}elseif($index <=2){
$start = 0; // index is at start
}else{
$start = $index-2; // index is somewhere in the middle
}
return implode(", ", array_slice($a, $start, 5));
}
https://3v4l.org/aNZsB
this is a "standalone" function to get spliced arrays of any size:
$a = [1,2,3,4,5,6,7,8,9];
echo "<pre>"; print_r(array_slicer($a, 2));
function array_slicer($arr, $start){
// initializations
$arr_len = count($arr);
$min_arr_len = 5; // the size of the spliced array
$previous_elements = 2; // number of elements to be selected before the $start
$next_elements = 2; // number of elements to be selected after the $start
$result = [];
// if the $start index doesn't exist in the given array, return false!
if($start<0 || $start>=$arr_len){
return false;
} elseif($arr_len <= $min_arr_len){ // if the size of the given array is less than the d size of the spliced array, return the whole array!
return $arr;
}
// check if the $start has less than ($previous_elements) before it
if($arr_len - ($arr_len - $start) < $previous_elements){
$next_elements += ($next_elements - ($arr_len - ($arr_len - $start)));
} elseif(($arr_len - 1 - $start) < $next_elements){ // check if the $start has less than ($next_elements) after it
$previous_elements += ($previous_elements - ($arr_len - 1 - $start));
}
for($i = ($start-$previous_elements); $i <= ($start + $next_elements); $i++){
if($i>-1 && $i<$arr_len){
$result[] = $arr[$i];
}
}
return $result;
}
You can define the bounds of where the array_slice() will begin by leveraging min() and max(). Assuming your array will always have at least 5 element, you can use:
array_slice($a, min(count($a) - 5, max(0, $index - 2)), 5)
The chosen index will be in the center of the sliced array unless it cannot be.
Dynamic Code: (Demo)
$a = [0, 1, 2, 3, 4, 5, 6, 7];
$count = count($a);
$span = 5; // most sensible with odd numbers
$center = (int)($span / 2);
foreach ($a as $i => $v) {
printf(
"%d: %s\n",
$i,
implode(
',',
array_slice(
$a,
min($count - $span, max(0, $i - $center)),
$span
)
)
);
}
Output:
0: 0,1,2,3,4
1: 0,1,2,3,4
2: 0,1,2,3,4
3: 1,2,3,4,5
4: 2,3,4,5,6
5: 3,4,5,6,7
6: 3,4,5,6,7
7: 3,4,5,6,7

array_splice() isn't working properly inside a loop

This code works as expected and removes the array element when the value is either 5 or 10. But it only works when I have 1 value which is 5 or 10 in the array.
If I have more than 1 value which is 5 or 10 it removes only 1 of them and leaves the other elements in the array.
My code:
for($i = 0; $i <= 10; $i++) {
if($somevar[$i] == 5 || $somevar[$i] == 10) {
echo 'the sumvar'.$somevar[$i].' exists<br>';
array_splice($somevar, $i, 1);
}
}
As an example if I have: [3, 5, 4] the result is as expected: [3, 4]. But if I have an array like: [3, 5, 10, 4] it just removes the 5, but not the 10: [3, 10, 4].
I can't seem to find it what I'm doing wrong and why my code doesn't work as expected?
You seem to miss that the array-elements are renumbered after the splice-operation.
You would have to adjust the loop-variable:
for($i = 0; $i < sizeof($somevar); $i++) {
if($somevar[$i] == 5 || $somevar[$i] == 10) {
echo 'the sumvar'.$somevar[$i].' exists<br>';
array_splice($somevar, $i, 1);
<b>$i--;</b>
}
}

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.

Categories