sort 2d array based on another array - php

i have a 1D arrayA and a 2D arrayB.
arrayA[0] = 'D'
arrayA[1] = 'U'
arrayA[3] = 'R'
arrayA[4] = 'B'
arrayA[5] = 'S'
arrayA[6] = 'H'
arrayB[0][0] = 'D' arrayB[0][1] = 2
arrayB[1][0] = 'B' arrayB[1][1] = 1
arrayB[2][0] = 'R' arrayB[2][1] = 1
arrayB[3][0] = 'U' arrayB[3][1] = 1
arrayB[4][0] = 'H' arrayB[4][1] = 0
arrayB[5][0] = 'S' arrayB[5][1] = 0
arrayB[x][y] is sorted - based on y.
I have to create a new array using the letters, first giving priority on y from arrayB[x][y].
But there are some same values in y like, 1 three times and 0 two times.
In this situation similar values will be sorted according to arrayA.
and the new array will sort like :
D, U, R, B, S, H
How can i do it efficiently ?
thanks in advance

In the code below, $string corresponds to arrayB[x][0], $weight corresponds to arrayB[x][1] and $order corresponds to arrayA:
<?php
$string = str_split('DBRUHS');
$weight = str_split('211100');
$result = '';
function my_sort($a, $b)
{
$order = str_split('DURBSH');
$a = array_search($a, $order);
$b = array_search($b, $order);
if ($a === $b) return 0;
if ($a === FALSE) return -1;
if ($b === FALSE) return 1;
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
arsort($weight);
$current_priority = -1;
$substring = array();
$max = count($weight);
$count = 1;
foreach ($weight as $position => $priority)
{
if ($count++ == $max)
{
$substring[] .= $string[$position];
$priority = $current_priority + 1;
}
if ($current_priority != $priority)
{
if (!empty($substring))
{
usort($substring, 'my_sort');
$result .= implode('', $substring);
}
$current_priority = $priority;
$substring = array($string[$position]);
}
else
{
$substring[] = $string[$position];
}
}
print_r(str_split($result));
?>

I tried this and it worked fine. a1 is the 1d array, a2 is the 2d.
EDIT: This works now.
function sortArr($a1, $a2) {
$t1 = array();
foreach ($a1 as $v) {
$t2 = array();
foreach ($a2 as $i=>$k) {
if ($k[0] == $v) {
$t2[0] = $k[0];
$t2[1] = $k[1];
$t1[$i] = $t2;
break;
}
}
}
return $t1;
}

Related

How to get the maximum possible sum of values of the edges’ endpoints php

The contents of this question have been removed due to a DMCA Takedown request by Codility Limited.
Here is the Simplets PHP solution for the Above question from the Codility test.
<?php
$A = [2,2,1,2];
$B = [1,3,4,4];
$w = [3,5,2,4,1];
$N = 5;
// $A = [1];
// $B = [3];
// $A = [1,3];
// $B = [2,4];
function solution ($N, $A, $B){
if(count($A) != count($B) || !is_int($N) )
{
return false;
}
$V = [];
$vertextCount = [];
foreach($A as $k=>$val){
if(!isset($vertextCount[$val])){
$vertextCount[$val] = 0;
}
$vertextCount[$val] += 1;
}
foreach($B as $k=>$val){
if(!isset($vertextCount[$val])){
$vertextCount[$val] = 0;
}
$vertextCount[$val] += 1;
}
if($vertextCount < $N)
{
$vertextCount[$N] = 0;
}
$VC = $vertextCount;
$tn = $N;
$wightArr = [];
while(count($VC) > 0){
$maxKey = current(array_keys($VC, max($VC)));
$wightArr[$maxKey] = $tn;
unset($VC[$maxKey]);
$tn--;
}
$sum = 0;
foreach($A as $k=>$val){
$sum += $wightArr[$A[$k]] + $wightArr[$B[$k]];
}
return $sum;
}
echo $sum = solution($N, $A, $B);
NOTE:- Tested against the 3 given Examples in the test, Not sure about all the test cases.

Find the successor & predecessor in a given array of integer values for a given integer

Let's say I have an array like that:
[12,3,4,5,8,9,11,20]
and a given number 7, then the predecessor/successor from the array would be 5/8 How do I find these numbers in an effective way?
At the moment I have the solution only for finding the successor via comparison.
Your need to iterate over the array and compare every number, than save the number, if it is more close to your needle, than the old one:
function precessorAndSuccessor(array $numbers, int $needle){
$pre = NULL;
$suc = NULL;
foreach($numbers as $number){
if($number < $needle){
if($pre === NULL || $pre < $number){
$pre = $number;
}
}elseif($number > $needle){
if($suc === NULL || $suc > $number){
$suc = $number;
}
}
}
return [
"predecessor" => $pre,
"successsor" => $suc
];
}
``
If you sort the array then just run through and check:
$num = 7;
$pre = $suc = false;
sort($array);
foreach($array as $v) {
if($v < $num) { $pre = $v; }
if($v > $num) { $suc = $v; break; }
}

Replace values in array with surrounding null,0

So I have a collection of integer values, which is built from a result of another function that can have different values every time. Consider the following in PHP:
$arr = [0,0,2,2,0,0,0,3,3];
Which i need to convert to:
$newArr = [null,0,2,2,0,null,0,3,3];
What i want to accomplish is: If a value is > 0, its neighbours should be 0, and the rest should be null.
What is the best strategy here?
Playing with operator precedence:
$zero = true;
$arr = [0,0,2,2,0,0,0,3,3];
$newArr = [];
foreach($arr as $k=>$v) {
if ($v) {
$newArr[] = $v;
$zero = false;
} else {
if ($zero and isset($arr[$k+1]) && !$arr[$k+1] || !isset($arr[$k+1]))
$newArr[] = null;
else
$newArr[] = 0;
$zero = true;
}
}
print_r($newArr);
Looping through the entire array, we evaluate each element for three conditions:
1.Element is zero.
2.Previous element is set, and it is equal to zero or null.
3.Next element is set, and it is equal to zero or null.
<?php
foreach($array as $key => $element)
{
if($element == 0 && ((isset($array[$key - 1]) && !$array[$key - 1]) || (isset($array[$key + 1]) && !$array[$key + 1])))
{
$array[$key] = null;
}
}
?>
I think it should work for you:
<?php
$arr = [0,0,2,2,0,0,0,3,3];
$new_array = $arr;
$array_count = count($arr);
for ($i=0; $i<$array_count; $i++) {
if ($i == 0 && $arr[$i+1] == 0) {
$new_array[$i] = null;
} elseif ($i == ($array_count-1) && $arr[$i-1] == 0) {
$new_array[$i] = null;
} elseif ($arr[$i-1] == 0 && $arr[$i+1] == 0) {
$new_array[$i] = null;
}
}
echo "<pre>";
print_r($new_array);
?>
We need to check for three conditions: is there, prev. is zero and next is zero.
You can combine first two conditions into the third one.
Broke it down for simplicity.
$array = [0,0,2,2,0,0,0,3,3];
$newArray = [];
foreach ($array as $key => $val) {
$previous = NULL;
$next = NULL;
if (isset($array[$key + 1])) {
$next = $array[$key + 1];
}
if ($key != 0) {
$previous = $array[$key - 1];
}
if ($val === 0 && $next == 0 && $previous == 0) {
$newArray[] = 'NULL';
} else {
$newArray[] = $val;
}
}
Another way to do this:
$arr = [0,0,2,2,0,0,0,3,3];
foreach($arr as $key => $value){
if($arr[$key] > 0 && isset($arr[$key - 1]) && $arr[$key - 1] == 0){
if(isset($arr[$key - 2]) && $arr[$key - 2] == 0){
$arr[$key - 2] = null;
}
}
if($arr[$key] > 0 && isset($arr[$key + 1]) && $arr[$key + 1] == 0){
if(isset($arr[$key + 2]) && $arr[$key + 2] == 0){
$arr[$key + 2] = null;
}
}
}
echo '<pre>';
print_r($arr);
echo '</pre>';
Here, i am looking for the positive value first then checking and if neighbor is 0 then set neighbor's neighbor to null.
<?php
$arr = [0,0,2,2,0,0,0,3,3];
$extra = [];
for($x=0; $x<count($arr); $x++){
if($arr[$x] == 0){
$tmp = isset($tmp)?$tmp:[];
$tmp[]=$x;
}else{
if(isset($tmp)){
$extra[] = $tmp;
unset($tmp);
}
}
}
foreach($extra as $subArr){
if(count($subArr) == 2){
$arr[$subArr[0]] = null;
$arr[$subArr[1]] = 0;
}else if(count($subArr) == 3){
$arr[$subArr[0]] = 0;
$arr[$subArr[1]] = null;
$arr[$subArr[2]] = 0;
}
}
var_dump($arr);
// YIELDS::
array (size=9)
0 => null
1 => int 0
2 => int 2
3 => int 2
4 => int 0
5 => null
6 => int 0
7 => int 3
8 => int 3

How to generate Combinations of fixed size from multiple arrays?

I need to find all combinations of items in several arrays with fixed subset size. For example, I have the 3 arrays :
$A = array('A1','A2','A3');
$B = array('B1','B2','B3');
$C = array('C1','C2','C3');
I want to generate combinations of size 2 from the above arrays. Like:
$Combinations = array(
[0] => array('A1', 'B1'),
[1] => array('A1', 'C1'),
[2] => array('A2', 'B1'),
[3] => array('A2', 'C1')
);
This solution is generating all combinations, but does not seem to have size parameter in it.
Looking for help!
$A = array('A1','A2','A3');
$B = array('B1','B2','B3');
$C = array('C1','C2','C3');
$All = array();
foreach ($A as $key1=>$value1){
foreach ($B as $key2=>$value2){
$All[] = array($value1,$value2 );
}
foreach ($C as $key3=>$value3){
$All[] = array($value1,$value3 );
}
}
print_r($All);
Check output here : https://eval.in/574060
Finally, found a solution. With the following script, you can combine any number of arrays with any number of elements per a combination. Please read the comments in the code and try to understand what happens.
<?php
$A = array('A1', 'A2', 'A3');
$B = array('B1', 'B2', 'B3');
$C = array('C1', 'C2', 'C3');
$combinationCount = 5;
$itemsPerCombination = 2;
$array = ['A', 'B', 'C'];
$combinations = array();
for ($x = 0; $x < $combinationCount; $x++) {
//to keep temporary names of arrays which come in a combination
$arrays = array();
for ($y = 0; $y < $itemsPerCombination; $y++) {
$valid = false;
while (!$valid) {
//get a random array, check if it is already in our selection
$arrayElement = $array[rand(0, count($array) - 1)];
if (in_array($arrayElement, $arrays)) {
$valid = false;
continue;
}
$arrays[] = $arrayElement;
$valid = true;
}
}
$found = false;
while (!$found) {
//for each selection in our selected arrays, take a random element and add to the combination.
$combination = array();
foreach ($arrays as $arr) {
$temp=$$arr;
$combination[] = $temp[rand(0, count($temp) - 1)];
}
if (in_array($combination, $combinations)) {
$found = false;
continue;
}
$combinations[] = $combination;
$found = true;
}
}
echo(json_encode($combinations));
?>

Finding 4 highest values from an array

Instead of just 1, how can I pick the 4 highest values from an array using max()?
You could use an SplMaxHeap
function maxN(array $numbers, $n)
{
$maxHeap = new SplMaxHeap;
foreach($numbers as $number) {
$maxHeap->insert($number);
}
return iterator_to_array(
new LimitIterator($maxHeap, 0, $n)
);
}
Usage (demo):
print_r( maxN( array(7,54,2,4,26,7,82,4,34), 4 ) );
You could try this:
$a = array(3,5,6,1,23,6,78,99);
asort($a);
var_dump(array_slice($a, -4));
HTH.
This will do it in Θ(n) time:
$a = $b = $c = $d = null;
foreach($array as $v) {
if(!isset($a) || $v > $a) {
$d = $c;
$c = $b;
$b = $a;
$a = $v;
}elseif(!isset($b) || $v > $b) {
$d = $c;
$c = $b;
$b = $v;
}elseif(!isset($c) || $v > $c) {
$d = $c;
$c = $v;
}elseif(!isset($d) || $v > $d) {
$d = $v;
}
}
$result = array($a, $b, $c, $d);
function maxs($ar, $count=4)
{
$res = array();
foreach ($ar as $v)
{
for ($i = 0;$i < $count;$i++)
{
if ($i >= count($res) || $v > $res[$i])
{
do
{
$tmp = $res[$i];
$res[$i] = $v;
$v = $tmp;
$i++;
}
while ($i < $count);
break;
}
}
}
return $res;
}
A simple method using php predefined functions.
<?php
$arr = array(6, 8, 3, 2, 7, 9);
rsort($arr);
$first = array_shift($arr);
$second = array_shift($arr);
$third = array_shift($arr);
echo $first; // print 9
echo $second; // print 8
echo $third; // print 7
?>
While storing itself you can maintain another array as soon as the new item is inserted check with the max value in the inner array if the item being inserted is greater insert this item. During the item pop do viceversa. From the inner maintained array you can get as many max numbers as possible.

Categories