Grouping elements in supergroups - php

At the moment I've got a set of arrays of elements, say,
[1, 2, 3]
[2, 4]
[5, 6, 7]
[1 , 44]
[5, 12]
etc...
What I want to do is to group these groups into supergroups if they share at least one element together. That is, the arrays above should become:
[1, 2, 3, 4, 44]
[5, 6, 7, 12]
The data I have is much larger and I wonder what is the efficient way of performing such operation.
My guess is take first array, go through all others, if there is intersection, join them and start from the top again, until there is no intersection of first with others. Then follow on to the second one etc...
Is there a better way to do it? I'm especially interested if it could be done easily in PHP, but pseudocode would be good as well..

So, this is the best I came up with:
$j = 0;
while(array_key_exists($j, $groups)){
$i = $j + 1;
while(array_key_exists($i, $groups)){
if(count(array_intersect($groups[$j], $groups[$i])) > 0){
$groups[$j] = array_merge($groups[$j], $groups[$i]);
$groups[$j] = array_unique($groups[$j]);
unset($groups[$i]);
$i = $j + 1;
$groups = array_values($groups);
}
else{
$i = $i + 1;
}
}
$j = $j + 1;
}

Related

How to get an Array of points between 2 3d vectors

Im looking for a way to get an array of points between 2 points that are 3d.
What I’ve found
So far while looking ive not found anything that is 3d, when I look for 3d it only returns a bunch of things of How to get distance between 2 points And thats not what im looking for!
I have found 1 good one about 2d points - here
However Ive found nothing about 3d, so sorry if this is duplicate.
Ive also tried search Stack Exchange Mathematics, and multiple other webpages, and still cant find anything that can answer my question.
More Details
Im going to give an example so that its more clear what I am looking for. Say I have 2 3d vectors (x1, y1, z1) and (x2, y2, z2). My points in this example will be (0, 0, 0) and (10, 10, 10).
After I have run these through the function I would want it to return an array of points something like this:
[1, 1, 1],
[2, 2, 2],
[3, 3, 3]
All the way up to 10.
Have you tried a 'for' loop?
function myFunction() {
$arr = array();
for ($i = 1; $i < 11; $i++) {
$arr[] = array($i, $i, $i);
}
return $arr;
}
$myArr = myFunction();
The result will be an array with each key having an array value incremented.
you can use see complete array...
print_r($myArr);
Or each individual value by using its key value...
echo $myArr[0][2]
Answer
I have now found the answer to my question above.
function logPointsOnLine(array $point1, array $point2, int $points) {
$vecs = [];
$delX = $point2[0] - $point1[0];
$delY = $point2[1] - $point1[1];
$delZ = $point2[2] - $point1[2];
for($i = 0; $i < $points; $i++) {
$newX = $point1[0] + $delX / ($points - 1) * $i;
$newY = $point1[1] + $delY / ($points - 1) * $i;
$newZ = $point1[2] + $delZ / ($points - 1) * $i;
array_push($vecs, array($newX, $newY, $newZ));
}
}
If you want to run it one way you could do it is:
$vec1 = array(10, 12, 32);
$vec2 = array(15, 60, 25);
$amt = 10;
$points = logPointsOnLine($vec1, $vec2, $amt);
print_r($points);

PHP: AdjacentElementsProduct - CodeFights https://app.codesignal.com/arcade/intro/level-2/

QUESTION:
Given an array of integers, find the pair of adjacent elements that has the largest product and return that product.
Example:
https://app.codesignal.com/arcade/intro/level-2
For inputArray = [3, 6, -2, -5, 7, 3], the output should be
adjacentElementsProduct(inputArray) = 21.
7 and 3 produce the largest product.
Input/Output
Input:
inputArray: [3, 6, -2, -5, 7, 3]
Expected Output:
21
SOLUTION: My code that doesn't work:
function adjacentElementsProduct($inputArray) {
$total = 0;
$temp = 0;
$maxProduct = 0;
$var = 0;
if ($inputArray.count == 1) return 0;
for ($i = 0; $i < $inputArray[$inputArray.count-1]; $i++) {
if ($inputArray[i] + $inputArray[i+1] > $maxProduct) {
$maxProduct = $inputArray[i] * $inputArray[i+1];
}
}
return $maxProduct;
}
As with any programming task, the trick is to tackle it piece by piece. You tend to find your code is more readable when you break problems down into small components.
You need to:
Find the product of adjacent elements in an array
Find the largest product in that group of values
You can approach this without a large number of variables, nesting, etc.
function adjacentElementsProduct(array $inputs) {
$products = [];
for ($i = 1; $i < count($inputs); $i++) {
$products[] = $inputs[$i - 1] * $inputs[$i];
}
return max($products);
}
All we're doing is looping through the input array, starting with the second element. Calculating the product of the previous element and the current element then putting the result into an array of products. Finally we run that through max() which is going to handle finding the largest value for us.
Important to note: there's no validation taking place here. Can you trust that your array will only ever contain numerical values? Will it always contain at least two elements? If not you'll want to account for that.
Here is how I would do it
$inputArray = [3, 6, -2, -5, 7, 3];
function adjacentElementsProduct($inputArray) {
$max = 0;
for($i = 0; $i < (sizeof($inputArray) - 1); $i++){
$b = $i+1;
if($inputArray[$i] > 0 && $inputArray[$b] > 0){
$max = (($inputArray[$i] * $inputArray[$b]) > $max) ? ($inputArray[$i] * $inputArray[$b]) : $max;
}
}
return $max;
}
echo adjacentElementsProduct($inputArray); // Outputs 21
function adjacentElementsProduct($inputArray) {
$res = [];
for($j=0;$j<count($inputArray);$j++){
$res[] = $inputArray[$j]*$inputArray[$j+1];
}
return (max($res) < 0) ? 0 : max($res);
}
As with any programming task, the trick is to tackle it piece by piece. You tend to find your code is more readable when you break problems down into small components.
You need to:
Find the product of adjacent elements in an array
Find the largest product in that group of values
In PHP its as below:
function adjacentElementsProduct($inputArray) {
$res = [];
for($j=1;$j<count($inputArray);$j++){
$res[] = $inputArray[$j-1]*$inputArray[$j];
}
return max($res);
}
$a = [3, 6, -2, -5, 7, 3]
echo adjacentElementsProduct($a); //21

Need an efficient way to break down a quantity into specified order sizes

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.

Decrypt the series - find number of continuous sequences of integers such that their sum is zero

The following is a programming task.
You are given a sequence of N integers. The task is to find the number of continuous sequences of integers such that their sum is zero.
For example if the sequence is:
2, -2, 6, -6, 8
There are 3 such sequences:
'2, -2'
'6, -6'
'2, -2, 6, -6'
I already have the following program written in PHP that reads the input from STDIN (first line containing the number of integers that follow.)
<?php
$n = fgets(STDIN) * 1;
$seq = array();
for ($i = 0; $i < $n; $i++) {
$seq[] = fgets( STDIN ) * 1;
}
$count = 0;
for( $i = 0; $i < $n; $i++)
{
$number = 0;
for( $j = $i; $j < $n; $j++)
{
$number += $seq[$j];
if( $number == 0 )
$count++;
}
}
echo 'count: ' . $count . PHP_EOL;
Input example
5
2
-2
6
-6
8
This works well for smaller sequences, but its efficiency is O(n^2).
What algorithm is appropriate - with possibly O(n) efficiency - for a sequence containing 100.000 integers?
Let's assume your data is stored in an array, and let it be arr.
Create an array sum, such that:
sum[i] = arr[0] + arr[1] + ... + arr[i]
And, in addition a single entry at the beginning with 0 (to handle a subarray that starts at the beginning and sums to zero)
Now, it is easy to see that for each two indices i,j such that i<j and sum[i]=sum[j], the continuous sequences arr[i+1]+arr[i+2]+...+arr[j] = 0.
By creating this array sum, you only have left to find how many duplicates are there. This cannot be done in O(n)1 (this is the element distinctness problem), but can be solved in O(nlogn) using sorting and then iterating and counting, which is still very fast for 100,000 entries.
Note, that if there are for example n duplicates of the number k in the array sum, there are Choose(n,2) = n(n-1)/2 continuous subsequences that are generated for these duplicates.
Example:
arr = [1,2,-2,5,6,-6,-5,8]
sum = [0,1,3,1,6,12,6,1,9]
sorted(sum) = [0,1,1,1,3,6,6,9,12]
There are 3 duplicates of 1 and 2 duplicates of 6, so you have total of:
Choose(3,2) + Choose(2,2) = 3*2/2 + 2/2 = 3+1 = 4
Which indeed match the 4 subsequences:
2,-2
2,-2,5,6,-6,-5
6,-6
5,6,-6,-5
(1) Without hashing, and then you will decay to O(n^2) worst case, but will benefit from O(n) average case, at the cost of O(n) extra space.
Since I can't reply to comments, this is a reply to amit's answer.
Maybe I have something wrong, but when applying your method to the original test case, we don't get the right answer:
input = [2, -2, 6, -6, 8]
sum = [2, 0, 6, 0, 8]
sorted(sum) = [0, 0, 2, 6, 8]
Since there are 2 duplicates of the number 0, this gives us (2*1)/2=1, which is not correct (correct answer would be 3).
What am I missing? Thanks

php/mysql compare arrays

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;

Categories