Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need to write a function that when i have an array with n numbers from -10 to 10 (without 0) returns quantity of pairs from the array which sum gives 0.
For example:
$input = array (3, 6, -3, 5, -10, 3, 10, 1, 7, -1, -9, -8, 7, 7, -7, -2, -7);
In example right answer is 5 (pairs are bolded)
i figure out something like that:
<?php
$array = [3, 6, -3, 5, -10, 3, 10, 1, 7, -1, -9, -8, 7, 7, -7, -2, -7];
function pairs($array=[]){
$copy = $array;
$arrayLength = count($copy);
$pairs=0;
while($arrayLength!=0){
$a = array_values($array)[0];
$b = -$a;
for( $i=1 ; $i==$arrayLength ; $i++ ){
if($array[$i]==$b){
unset($array[$i]);
$pairs++;
$arrayLength--;
}
else{
unset($array[$i]);
$arrayLength--;
}
}
return $pairs;
}
unset($copy);
}
var_dump(pairs($array));
?>
Try out this one:
function pairs($array=[]){
$pairs = [];
// counting the positive and negative of each number in the set
foreach($array as $v){
$av = abs($v);
if(!isset($pairs[$av]))
$pairs[$av] = [
'pos' => 0,
'neg' => 0
];
($v > 0) ? $pairs[$av]['pos']++ : $pairs[$av]['neg']++;
}
$pair_count = 0;
// getting the number of pairs for each number, based on those counts
foreach($pairs as $pair){
$pair_count += min($pair['pos'],$pair['neg']);
}
return $pair_count;
}
DEMO
This gets rid of the annoying need to rebuild the array indexes every time you unset (part of where your issues with your provided function are coming from), and also makes it so you only need to loop through it twice and therefore is more efficient, especially for large data sets.
Related
So I need a method that will break down an order into the specified sizes. For example:
orderBreakdown(40, [4, 8, 12, 16]);
Would return [16, 16, 8] (an array of the orders). It needs to have the most efficient breakdown (can't be 12, 12, 12, 4). It also has to be extremely flexible - it can fail (obviously some quantities can't be broken down, for example 39 in that case).
Right now I have:
function quantityBreakdown(int $count, array $units)
{
sort($units);
$units = array_reverse($units); //order units from large to small
$orders = [];
$original_count = $count;
while ($count > 0 && !empty($units))
{
for($i = 0; $i < count($units); $i++)
{
$unit = $units[$i];
while($count >= $unit){
array_push($orders, $unit);
$count = $count - $unit;
}
}
if ($count > 0){
$count = $original_count;
$orders = [];
array_shift($units);
}
}
return $orders;
}
This works in a lot of cases:
quantityBreakdown(19, [6, 8, 11, 17]); will return [11, 8] for example. But there are some cases when it will return non-optimal results. quantityBreakdown(36, [6, 8, 11, 17]) will return [6, 6, 6, 6, 6, 6], when optimally it should return [17, 11, 8]. I'm a bit at a loss of where to go from here.
Assuming that the array is ordered you can have two pivots, one at the start and one in the end. So if you want to get a specific value, you can just add both values of each of the pivots. In this sense, if the result is too small just move the left pivot so your result increase and you your result is too big move the right pivot so your result decrease. If you don't get the desired result just add more pivots so you can duplicate numbers.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
$a = array(2, 6, 24, 16, 7, 10);
I know how to add all the numbers using array_sum() but if I want to add only the numbers between 2 and 16 how can do that?
This is one of the solution that that I've come up with:
$a = array(2, 6, 24, 16, 7, 10);
$r = array_slice($a, 0, -2);
print_r (array_sum($r));
Just want to know if there is any other way to get the result.
To deal with dynamic bound limits you can extend the initial approach(array_slice + array_sum) using array_search function:
$arr = [2, 6, 24, 16, 7, 10];
$a = 10;
$b = 24;
$lowerBound = array_search($a, $arr);
$upperBound = array_search($b, $arr);
if (($low = $lowerBound) > $upperBound) { // if bounds were confused
$lowerBound = $upperBound;
$upperBound = $low;
}
$sum = array_sum(array_slice($arr, $lowerBound, $upperBound - $lowerBound + 1));
print_r($sum); // 57
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been working on one problem:
Find the largest group of consecutive numbers in an array.
Say we have an array [5, 43, 4, 56, 3, 2, 44, 57, 58, 1], the biggest group of consecutive numbers in this array is 5 (1, 2, 3, 4, and 5).
The solution algorithm must be time complexity of O(n).
I have solved this with the following ruby code but I am having trouble porting it to PHP as the solution requires.
arr = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]
result = []
stage = []
for i in arr:
if len(stage) > 0 and i != stage[-1]+1:
if len(stage) > 1:
result.append(stage)
stage = []
stage.append(i)
print result
$a = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4];
$res = [];
$stage = [];
foreach($a as $i) {
if(count($stage) > 0 && $i != $stage[count($stage)-1]+1) {
if(count($stage) > 1) {
$res[] = $stage;
}
$stage = [];
}
$stage[] = $i;
}
print_r($res);
It's not O(n) but you can try this:
// Define array
$array = array(5,8,3,2,10,11,15,13,12,1,4,5,16);
// Sorting
asort($array);
$previous = null;
$result = array();
$consecutiveArray = array();
// Slice array by consecutive sequences
foreach($array as $number) {
if ($number == $previous + 1) {
$consecutiveArray[] = $number;
} else {
$result[] = $consecutiveArray;
$consecutiveArray = array($number);
}
$previous = $number;
}
$result[] = $consecutiveArray;
// Get length of each sub array
$count = array_map('count', $result);
You can get max length by max($count).
This solution gives you following array:
array(
0 => array(1,2,3,4,5)
1 => array(5)
2 => array(8)
3 => array(10,11,12,13)
4 => array(15,16)
Here is a python (my PHP is not too good) that does what your description asks, in o(n) if your sequence is decreasing:
lists = dict()
for i in val:
if i in lists:
continue
a = {i}
if (i + 1) in lists:
b = lists[i+1]
b.update(a)
a = b
if (i - 1) in lists:
b = lists[i-1]
# this messes up the complexity
for k in b:
lists[k] = a
a.update(b)
lists[i] = a
The idea is that lists maintain a dict of sets indexed on all the elements in the list. Whenever you encounter a new element, the previous and next sets are merged, if present.
The update operation is technically o(n), but it is not compounded by the external loop, as there can only be n insertion into sets by merging. The overall is o(n)
If the sequence is not sorted, the merge of the +1 and -1 sets gives a not-so-good complexity.
First of all, thanks for looking at my question.
I only want to add up the positive numbers in the $numbers using a if,else statement.
$numbers = array (1, 8, 12, 7, 14, -13, 8, 1, -1, 14, 7);
$total = 0;
if ($numbers < 0 {
$numbers = 0;
}
elseif (now i want only the positive numbers to add up in the $total.)
I'm an first years student and I am trying to understand the logic.
I'm not gonna give the direct answer, but the way here is you need a simple loop, can be for or a foreach loop, so every iteration you just need to check whether the current number in the loop is grater than zero.
Example:
$numbers = array (1, 8, 12, 7, 14, -13, 8, 1, -1, 14, 7);
$total = 0;
foreach($numbers as $number) { // each loop, this `$number` will hold each number inside that array
if($number > 0) { // if its greater than zero, then make the arithmetic here inside the if block
// add them up here
// $total
} else {
// so if the number is less than zero, it will go to this block
}
}
Or as michael said in the comments, a function also can be used in this purpose:
$numbers = array (1, 8, 12, 7, 14, -13, 8, 1, -1, 14, 7);
$total = array_sum(array_filter($numbers, function ($num){
return $num > 0;
}));
echo $total;
$numbers = array (1, 8, 12, 7, 14, -13, 8, 1, -1, 14, 7);
$total = 0;
foreach($numbers as $number)
{
if($number > 0)
$total += $number;
}
this loops through all elements of the array(foreach = for each number in the array) and checks if the element is bigger than 0, if it is, add it to the $total
My question:
I got a phpmyadmin database ( and using php 5),
with 2 tables to compare a football toto tournament.
the strings that i must compaire are like the following :
1|2|3|1|1|2|3|1|2|3|3
( in total 43 numbers) i know that i must use explode for taking out the "|" between them (because its saved as a string)
but the final score is also saved like that. so i must compare all (guessed outcomes from matches with the final score string. how do it do it so that i can see who has got the most guessed right?
And that it would be shown as 1e place, 2e place, 3e place and so on?
Would be a great help,
sorry if i lack at something.
I'm not entirely certain that I understand the question correctly, but if the two arrays are of the same length, you can use the same iterator for both of them.
After you've explode()d the strings into arrays:
$one = array(1, 2, 3, 4, 5);
$two = array(8, 2, 3, 6, 1);
$results = array();
for ($i = 0; $i < count($one); $i++) {
$results[$i] = $one[$i] - $two[$i];
}
Note that the above code is untested, and instead of whatever calculation you use, I just subtract the value of each $two element from each $one element.
Hope it helps.
if i understand the question well...
$guess = array(1, 2, 1, 3, 1, 2, 3);
$real = array(2, 2, 1, 2, 2, 1, 1);
$score = 0;
$length = count($real);
for($i = 0; $i < $length; $i++) {
if($guess[$i] == $real[$i])
++$score;
}
echo $score;