I have a N*N Matrix.Now i want to know the diagonal difference of this Matrix.What will be the best approach of this solution?
I am trying with given approach:
Such as it is 3*3 Matrix say it is:
11 15 85
66 72 21
14 21 47
the diagonal simple formula will be:
firstD= (11+72+47) = 130
secondD = (85+72+14)= 171
diagonalDiff = |firstD - secondD| = |130-171| = 41
If I count every row such as first to find out firstD (First row's first value + Sec row's Sec value + Third row's third value+..).This is my thinking.
Can anyone tell me best approaches?
Try this:
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$firstD += $arr[$i++][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);//41
Model your matrix with a multi-dimensional array and iterate through it. The easiest way should be the following:
<?
$matrix = array(array(1,2,3),array(4,5,6),array(7,8,9)); //Insert or define your matrix here..
$n = count($matrix); //Size of matrix, thanks to VolkerK
$firstD = 0;
$lastD = 0;
for($i = 0; $i < $n; $i++){
$firstD += $matrix[$i][$i];
$lastD += $matrix[$i][$n-$i-1];
}
echo $firstD."\n";
echo $lastD;
Here is a pseudo code for your problem using one simple loop:
// $array - predefined 2 dimentional array with $N rows and $N columns
$result = 0;
for ($i=0;$i<$N;$i++) {
$result += ($array[$i,$i] - &array[$i,$N-$i-1]);
}
return echo abs($result);
that way you can do the calculation in one pass, and do a diff between two elements in each row insead of calculation the sum of each diagonal
Try this:
function diagonalDifference($arr) {
$left = 0;
$right = 0;
$i = 0;
foreach($arr as $ar){
$left+= $ar[0+$i];
$right+= $ar[count($ar) - (1+$i)];
$i++;
}
return abs($left - $right);
}
Try this
$result=0;
for($i=0;$i<=count($arr)-1;$i++){
$result= $result+($arr[$i][$i])-($arr[(count($arr)-1-$i)] [$i]);
}
return abs($result);
This is the code you need:
$first = 0;
$second = 0;
for($i = 0; $i < N; $i++) {
for($j = 0; $j < N; $j++) {
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == N) {
$second += $matrix[$i][$j];
}
}
}
$diagonalDiff = abs($first - $second);
Where $matrix is a N*N array
Just using the function array_reduce:
function diagonalDifference($arr) {
$i = 0;
$n = count($arr);
return abs(array_reduce($arr,
function ($c, $str) use (&$i, $n ) {
$i++;
return $c + $str[$i-1] - $str[$n-$i];
}, 0));
}
demo
you can try this :
$first_diag=$second_diag=0;
$matrix=array(array(11,15,85),array(66,72,21),array(14,21,47));
foreach($matrix as $index=>$sub_array){
$first_diag +=$sub_array[$index];
$second_diag +=$sub_array[count($matrix)-1-$index];
}
print abs ($first_diag-$second_diag);
For one you can use a matrix library like Math_Matrix. But if this is the only operation you are gona need then it's best to write a generalized function for this using the same method you quoted yourself.
function diagonalDiff($n){
$firstD = 0;
$secondD = 0;
for($i=0;$i<$n;$i++){
for($j=0;$j<$n;$j++){
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == $n) {
$secondD += $matrix[$i][$j];
}
}
}
return abs($firstD-$secondD);
}
Should give you the answer you need for a matrix of a given size $n. (Only square Matrixes ofcourse :) )
Another better solution and it's easy to understand:
<?php
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$i++;
$firstD += $arr[$j][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);
?>
DEMO
Recently solved this question in Hacker Rank.
<?php
$m=array(array(3,4,-1,11,2),
array(-3,2,1,6,9),
array(3,4,6,5,-2),
array(1,9,9,7,-3),
array(12,9,16,7,-3));
echo count($m)."<br>";
$i=0;
$j=0;
$ek=0;
$k=0;
$n=1;
$es=count($m)-1;
for($i=0;$i<count($m);$i++)
{
for($j=0;$j<count($m);$j++)
{
echo $m[$i][$j]." ";
}
echo "<br>";
}
echo "<br>";
for($k=0;$k<count($m);$k++)
{
for($n=0;$n<count($m);$n++)
{
if($k==$n){
$ek=$ek+$m[$k][$n];
}
}
echo "<br>";
}
echo "<hr>";
$p=0;
for($k=0;$k<count($m);$k++)
{
echo $m[$k][$es-$p]."<br> ";
$p++;
}
?>
Sorry I used different variable names, I had to take this to my vs code.
$b = array(
array(1,2,5),
array(3,4,5),
array(3,4,5)
);
//So for each diag
echo $b[0][0] + $b[1][1] + $b[2][2]; //to sum the first diag
echo $b[0][2] + $b[1][1] + $b[2][0]; //to sum the second diag
//notice the pattern 00, 11, 22 vs 02,11, 20. hence why I have written the function below
function difference($b){
$d1 = 0;
$d2 = 0;
$count = count($b);
for($i=0; $i<$count; $i++){
$d1 += $b[$i][$i];
$d2 += $b[$i][$count-1-$i];
}
return abs($d1 - $d2);
}
I had the same issue, the instructions was given by the site, mislead me. However, I solved it in this way,
$n = count and store the length of input array
//define variables to store first diagonals and second diagonals
$fd = 0;
$sd = 0;
//loop through the 2D array with $i increment
$j = get an array from the main array
//in each iteration
$pd += get the values from the left to the right and add;
$sd += get the values from the right to the left and add;
}
find absolute difference between the sums using built in abs function and return it;
I think this would help someone
Related
I have code like this
$jumlahcolspan = array();//new array
$horizontaldeep = 5;
$level = array(5,4,3,8,7);//old array
for ($j = 0; $j < $horizontaldeep; $j++) {
$jml = 1;
for ($i = $j + 1; $i < $horizontaldeep; $i++) {
$jml = $level[$i] * $jml;
}
array_push($jumlahcolspan, $jml);
}
To put it simple, what I want to get is to multiply old array value which index start from $i+1 to the last and push it to another array.
So, its some thing like this
old array: [5, 4, 3, 8, 7]
new array: [4*3*8*7, 3*8*7, 7, 1]
I've tried this but it doesn't work also
for ($j = 0; $j < $horizontaldeep; $j++) {
$jml = 1;
for ($i = $j + 1; $i < $horizontaldeep; $i++) {
global $jml;
$jml = $level[$i] * $jml;
}
array_push($jumlahcolspan, $jml);
}
Tried this too but not work also.
for ($j = 0; $j < $horizontaldeep; $j++) {
array_push($jumlahcolspan, array_product(array_slice($level, $j+1)));
}
Note: now I'm reviewing my full code. May be something not right in my code.
I think the problem is related to $jml variable but I can't figure how to solve that. Can anyone help me?
One approach would be to use a Recursive Function to achieve that goal. The Recursive Function below demonstrates how. And, by the way, you may as well quick-test it here.
<?php
$oldArray = [5,4,3,8,7];
function arrayMatrixMultiply(array $old, array &$newArray=[]){
$result = 1;
foreach($old as $key=>$value){
if($key != 0){
$result*=$value;
}
}
$newArray[] = $result;
array_splice($old, 0, 1);
if(!empty($old)){
// JUST RECURSE TILL THE $oldArray BECOMES EMPTY
arrayMatrixMultiply($old, $newArray);
}
return $newArray;
}
$newArray = arrayMatrixMultiply($oldArray);
var_dump($newArray);
// PRODUCES::
array (size=5)
0 => int 672
1 => int 168
2 => int 56
3 => int 7
I need to calculate from a given array the number that is equal or higher and closest to a given number in PHP. Example:
Number to fetch:
6.85505196
Array to calculate:
3.11350000
4.38350000
4.04610000
3.99410000
2.86135817
0.50000000
Only correct combination should be:
3.99410000 + 2.86135817 = 6.85545817
Can somebody help me? It's been 3 hours I'm getting mad!
UPDATE: I finally finished my code as following:
$arr = array(3.1135, 4.3835, 4.0461, 3.9941, 2.86135817, 0.5);
$fetch = 6.85505196;
$bestsum = get_fee($arr, $fetch);
print($bestsum);
function get_fee($arr, $fetch) {
$bestsum = 999999999;
$combo = array();
$result = array();
for ($i = 0; $i<count($arr); $i++) {
combinations($arr, $i+1, $combo);
}
foreach ($combo as $idx => $arr) {
$sum = 0;
foreach ($arr as $value) {
$result[$idx] += $value;
}
if ($result[$idx] >= $fetch && $result[$idx] < $bestsum) $bestsum = $result[$idx];
}
return $bestsum;
}
function combinations($arr, $level, &$combo, $curr = array()) {
for($j = 0; $j < count($arr); $j++) {
$new = array_merge($curr, array($arr[$j]));
if($level == 1) {
sort($new);
if (!in_array($new, $combo)) {
$combo[] = $new;
}
} else {
combinations($arr, $level - 1, $combo, $new);
}
}
}
I hope the following example might help you. Please try this
<?php
$array = array(
"3.11350000",
"4.38350000",
"4.04610000",
"3.99410000",
"2.86135817",
"0.50000000"
);
echo "<pre>";
print_r($array);// it will print your array
for($i=0; $i<count($array); $i++)
{
$j=$i+1;
for($j;$j<count($array); $j++)
{
$sum = $array[$i] + $array[$j];
// echo $array[$i]. " + ".$array[$j]." = ".$sum."<br>"; //this will display all the combination of sum
if($sum >= 6.85505196 && ($sum <= round(6.85505196)) )//change the condition according to your requirement
{
echo "The correct combinations are:<br/><br/>";
echo "<b>". $array[$i]. " + ".$array[$j]." = ".$sum."<b>";
echo "<br/>";
}
}
echo "<br/>";
}
?>
We will get the result as below
Array
(
[0] => 3.11350000
[1] => 4.38350000
[2] => 4.04610000
[3] => 3.99410000
[4] => 2.86135817
[5] => 0.50000000
)
The correct combinations are:
4.04610000 + 2.86135817 = 6.90745817
3.99410000 + 2.86135817 = 6.85545817
You should do it in two steps:
a. Work out (or look up) an algorithm to do the job.
b. Implement it.
You don't say what you've managed in the three hours you worked on this, so here's a "brute force" (read: dumb) algorithm that will do the job:
Use a variable that will keep your best sum so far. It can start out as zero:
$bestsum = 0;
Try all single numbers, then all sums of two numbers, then all sums of three numbers, etc.: Every time you find a number that meets your criteria and is better than the current $bestsum, set $bestsum to it. Also set a second variable, $summands, to an array of the numbers you used to get this result. (Otherwise you won't know how you got the solution). Whenever you find an even better solution, update both variables.
When you've tried every number combination, your two variables contain the best solution. Print them out.
That's all. It's guaranteed to work correctly, since it tries all possibilities. There are all sorts of details to fill in, but you can get to work and ask here for help with specific tasks if you get stuck.
Thank you all for your help!
My code is working pretty cool when is needed to fetch one or two numbers (addition) only. But can't figure out how to add more combinations up to the total count of elements in my given array.
I mean if there are, let's say, 8 numbers in my array I want to try all possible combinations (additions to each other) as well.
My actual code is:
$bestsum = 1000000;
for ($i = 0; $i < count($txinfo["vout"]); $i++) {
if ($txinfo["vout"][$i]["value"] >= $spent && $txinfo["vout"][$i]["value"] < $bestsum) {
$bestsum = $txinfo["vout"][$i]["value"];
}
}
for($i = 0; $i < count($txinfo["vout"]); $i++) {
$j = $i + 1;
for($j; $j < count($txinfo["vout"]); $j++) {
$sum = $txinfo["vout"][$i]["value"] + $txinfo["vout"][$j]["value"];
if($sum >= $spent && $sum < $bestsum) {
$bestsum = $sum;
}
}
}
$fee = bcsub($bestsum, $spent, 8);
print("Fee: ".$fee);
New updated code.
<?php
$x = 6.85505196;
$num = array(3.1135, 4.3835, 4.0461, 3.9941, 2.86135817, 0.5);
asort($num); //sort the array
$low = $num[0]; // lowest value in the array
$maxpossible = $x+$low; // this is the maximum possible answer, as we require the number that is equal or higher and closest to a given number
$num = array_values($num);
$iterations = $x/$num[0]; // possible combinations loop, to equate to the sum of the given number using the lowest number
$sum=$num;
$newsum = $sum;
$k=count($num);
for($j=0; $j<=$iterations; $j++){
$l = count($sum);
for($i=0; $i<$l; $i++){
$genSum = $sum[$j]+$sum[$i];
if($genSum <= $maxpossible){
$newsum[$k] = $genSum;
$k++;
}
}
$newsum = array_unique($newsum);
$newsum = array_values($newsum);
$k = count($newsum);
$sum = $newsum;
}
asort($newsum);
$newsum = array_values($newsum);
for($i=0; $i<count($newsum); $i++){
if($x<=$newsum[$i]){
echo "\nMaximum Possible Number = ".$newsum[$i];
break;
}
}
?>
I have written the following code to count the number of string occurrences in a given file.
PHP
<?php
$p = fopen("g.txt", "r");
$q = fread($p, filesize("g.txt"));
$t = explode(" ", $q);
$m = explode(" ", $q);
$i = 0;
$j = 0;
$r = 0;
$count = 0;
$c = count($t);
$d = array();
echo "count of".
"<br/>";
for ($i = 0; $i < $c; $i++) {
for ($j = $i; $j < $c; $j++) {
if ($t[$i] == $t[$j]) {
$count = $count + 1;
}
}
for ($r = $i + 1; $r < $c; $r++) {
if ($t[$i] == $t[$r])
unset($t[$r]);
}
echo $t[$i].
"=".$count.
"<br/>";
$count = 0;
}
?>
I am getting a notice of undefined offset on line numbers 17 and 24, though my output is coming out to be correct. Can you please help me in rectifying the above problem?
The problem is that you are deleting items from the array $t. You saved the count in $c, but the actual count will change by your last inner loop.
Even if you replace $c by count($t) everywhere, it will go wrong, because the last loop should be in reverse order, otherwise you skip items. For instance if you have the list 'a', 'b', 'c'. then when you delete 'b' and increment $r, you will not check 'c' at all.
So, if I fix those things, your code becomes as below. Although I didn't really check it for other issues. Frankly, I don't really get what is should do. ;-)
<?php
$p=fopen("g.txt","r");
$q=fread($p,filesize("g.txt"));
$t=explode(" ",$q);
$m=explode(" ",$q);
$i=0;
$j=0;
$r=0;
$count=0;
$d=array();
echo "count of"."<br/>";
for($i=0; $i<count($t); $i++)
{
for($j=$i; $j<count($t); $j++)
{
if($t[$i]==$t[$j])
{
$count=$count+1;
}
}
for($r=count($t) - 1; $r > $i; $r--)
{
if($t[$i]==$t[$r])
unset($t[$r]);
}
echo $t[$i]."=".$count."<br/>";
$count=0;
}
?>
In conclusion, you should do more tests. If the outcome of this script was okay, then it was by accident.
Starter with the logic implementation through programming so please find my honest efforts for project Euler Ques, although i tried various attempts to solve but could not get through it :(
Sum I am getting from this is - 257112. I added +2 in the sum to count for a[1] = 2 in the series, but its not working, also I am currently passing a static value 45 for $num but i think it is not the correct way, let me know where I am lagging in logic for the question.
Each new term in the Fibonacci sequence is generated by adding the
previous two terms. By starting with 1 and 2, the first 10 terms will
be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not
exceed four million, find the sum of the even-valued terms.
this is the code I tried -->
$a = array();
$a[0] = 1; $a[1] = 2; $num = 45; $i= 0; $sum = 0; $stop = $num -2;
for($i; $i < $stop ; $i++ ) {
$a[$i+2] = $a[$i+1] + $a[$i];
if( $a[$i+2]%2 == 0 && $a[$i+2] <= 400000 )
{
$sum += $a[$i+2];
}
}
echo "<pre>";
print_r($a);
echo "<br>"."Sum is : ".$sum;
EDIT - It was an error to add an extra zero to make it 4 million, although I am looking something for $num not to be static (as 45 I just mentioned randomly, although its working but its not a clean solution)
Make it simple, no arrays and make it quick. You are only looking for the sum, nothing else:
$a=1;$b=2;$sum=2;
while($b<4000000){
$c=$b+$a;
if($c%2==0)
$sum+=$c;
$a=$b;
$b=$c;
}
echo $sum;
If 4,000,000 counted, then it would be $b<=4000000
<?php
$f0=0;/* declaring variables */
$f1=1;
$f2=0;
$n=0; /* the series range */
while($n<20)
{
$f2=$f0+$f1;
echo $f2."<br>";
$f0=$f1;
$f1=$f2;
$n++;
}
?>
<?php
$f0=0;/* declaring variables */
$f1=1;
$f2=0;
$n=0; /* the series range */
while($n < $stop){
$f2=$f0+$f1;
$temp[] = $f2;
$f0=$f1;
$f1=$f2;
$n++;
}
var_dump($temp);
?>
You can check out same example here
This is pretty simple:
$prev = 0;
$curr = 1;
$next = 1;
for ($i=0; $i <= 10; $i++) {
$prev = $next;
$curr = $i;
$next = $prev + $curr;
echo $next.'<br/>';
}
Try this:
function fibonacci_series($n) {
$f1 = -1;
$f2 = 1;
for ($i = 1; $i <= $n; $i++) {
$f = $f1 + $f2;
$f1 = $f2;
$f2 = $f;
echo "$f<br />";
}
}
echo fibonacci_series(5);
<?php
function sortArray() {
$inputArray = array(8, 2, 7, 4, 5);
$outArray = array();
for($x=1; $x<=100; $x++) {
if (in_array($x, $inputArray)) {
array_push($outArray, $x);
}
}
return $outArray;
}
$sortArray = sortArray();
foreach ($sortArray as $value) {
echo $value . "<br />";
}
?>
I have this code but there are two problems
What if my numbers in array are greater than 100?
Also, I'd like to see more than one method of sorting
Here is the way of sorting.
<?php
$array=array('2','4','8','5','1','7','6','9','10','3');
echo "Unsorted array is: ";
echo "<br />";
print_r($array);
for($j = 0; $j < count($array); $j ++) {
for($i = 0; $i < count($array)-1; $i ++){
if($array[$i] > $array[$i+1]) {
$temp = $array[$i+1];
$array[$i+1]=$array[$i];
$array[$i]=$temp;
}
}
}
echo "Sorted Array is: ";
echo "<br />";
print_r($array);
?>
Most of the other answers use two for loops to sort an array. At first the code seemed fairly straight and even I thought of the same. But then I wanted to investigate further. How efficient is this method? So using an array of 10,000 values, I used the two for loops method and got an execution time of 7.5 seconds
This is way too much. I'm sure PHP can't be this sloppy. So next I tested the in-built PHP rsort() function and got a time of 0.003 seconds.
Some research gave me the answer that PHP uses a quicksort algorithm to sort indexed arrays with a recursive function. I dug deeper and found a few examples of quicksearch for C++, Java etc. So, I replicated them in PHP, as follows:
/*
The main function that implements QuickSort
arr --> Array to be sorted,
low --> Starting index,
high --> Ending index
*/
function quickSort(&$arr, $low, $high)
{
if ($low < $high)
{
/* pi is partitioning index, arr[p] is now
at right place */
$pi = partition($arr, $low, $high);
// Separately sort elements before
// partition and after partition
quickSort($arr, $low, $pi - 1);
quickSort($arr, $pi + 1, $high);
}
return $arr;
}
function partition (&$arr, $low = 0, $high)
{
$pivot = $arr[$high]; // pivot
$i = ($low - 1); // Index of smaller element
for ($j = $low; $j <= $high-1; $j++)
{
// If current element is smaller than or
// equal to pivot
if ($arr[$j] <= $pivot)
{
$i++; // increment index of smaller element
swap($arr[$i], $arr[$j]);
}
}
swap($arr[$i + 1], $arr[$high]);
return ($i + 1);
}
function swap(&$a, &$b){
$t = $a;
$a = $b;
$b = $t;
}
The time taken by this algorithm came out be: 0.023 seconds. Not as fast as rsort() but satisfactory.
This is my Quicksort algorithm in PHP:
<?php
$array = [1, 4, 3, 5, 9, 6, 1, 6, 4, 1, 1, 4, 5, 6, 6, 7, 2, 1, 4, 0];
$j = count($array);
$t = $j-1;
while($j>=0){
for ($i=0; $i < $t; $i++) {
$aux = $array[$i];
if($array[$i]>$array[$i+1]){
$array[$i] = $array[$i+1];
$array[$i+1] = $aux;
}
}
$j--;
}
print_r($array);
Sorting an array without using the built-in method but all the answers use the pre-defined method count.
I am just trying to refactor it. Please find the below answer.
$array = [50,12, 30, 10, 9, 14];
$count = 0;
foreach($array as $elem){
$count++;
}
for ($i = 0; $i < $count; $i++) {
for ($j = 0; $j < $count - 1; $j++) {
if ($array[$j] > $array[$j + 1]) {
$temp = $array[$j];
$array[$j] = $array[$j + 1];
$array[$j +1] = $temp;
}
}
}
print_r($array);