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

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);

Related

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

How to generate random numbers to produce a non-standard distributionin PHP

I've searched through a number of similar questions, but unfortunately I haven't been able to find an answer to this problem. I hope someone can point me in the right direction.
I need to come up with a PHP function which will produce a random number within a set range and mean. The range, in my case, will always be 1 to 100. The mean could be anything within the range.
For example...
r = f(x)
where...
r = the resulting random number
x = the mean
...running this function in a loop should produce random values where the average of the resulting values should be very close to x. (The more times we loop the closer we get to x)
Running the function in a loop, assuming x = 10, should produce a curve similar to this:
+
+ +
+ +
+ +
+ +
Where the curve starts at 1, peeks at 10, and ends at 100.
Unfortunately, I'm not well versed in statistics. Perhaps someone can help me word this problem correctly to find a solution?
interesting question. I'll sum it up:
We need a funcion f(x)
f returns an integer
if we run f a million times the average of the integer is x(or very close at least)
I am sure there are several approaches, but this uses the binomial distribution: http://en.wikipedia.org/wiki/Binomial_distribution
Here is the code:
function f($x){
$min = 0;
$max = 100;
$curve = 1.1;
$mean = $x;
$precision = 5; //higher is more precise but slower
$dist = array();
$lastval = $precision;
$belowsize = $mean-$min;
$abovesize = $max-$mean;
$belowfactor = pow(pow($curve,50),1/$belowsize);
$left = 0;
for($i = $min; $i< $mean; $i++){
$dist[$i] = round($lastval*$belowfactor);
$lastval = $lastval*$belowfactor;
$left += $dist[$i];
}
$dist[$mean] = round($lastval*$belowfactor);
$abovefactor = pow($left,1/$abovesize);
for($i = $mean+1; $i <= $max; $i++){
$dist[$i] = round($left-$left/$abovefactor);
$left = $left/$abovefactor;
}
$map = array();
foreach ($dist as $int => $quantity) {
for ($x = 0; $x < $quantity; $x++) {
$map[] = $int;
}
}
shuffle($map);
return current($map);
}
You can test it out like this(worked for me):
$results = array();
for($i = 0;$i<100;$i++){
$results[] = f(20);
}
$average = array_sum($results) / count($results);
echo $average;
It gives a distribution curve that looks like this:
I'm not sure if I got what you mean, even if I didn't this is still a pretty neat snippet:
<?php
function array_avg($array) { // Returns the average (mean) of the numbers in an array
return array_sum($array)/count($array);
}
function randomFromMean($x, $min = 1, $max = 100, $leniency = 3) {
/*
$x The number that you want to get close to
$min The minimum number in the range
$max Self-explanatory
$leniency How far off of $x can the result be
*/
$res = [mt_rand($min,$max)];
while (true) {
$res_avg = array_avg($res);
if ($res_avg >= ($x - $leniency) && $res_avg <= ($x + $leniency)) {
return $res;
break;
}
else if ($res_avg > $x && $res_avg < $max) {
array_push($res,mt_rand($min, $x));
}
else if ($res_avg > $min && $res_avg < $x) {
array_push($res, mt_rand($x,$max));
}
}
}
$res = randomFromMean(22); // This function returns an array of random numbers that have a mean close to the first param.
?>
If you then var_dump($res), You get something like this:
array (size=4)
0 => int 18
1 => int 54
2 => int 22
3 => int 4
EDIT: Using a low value for $leniency (like 1 or 2) will result in huge arrays, since testing, I recommend a leniency of around 3.

PHP running average of multiple array value differences

First, I have been programming in PHP for all of two weeks. So, please excuse my ignorance.
Here is my problem. I am trying to find essentially the running average of multiple difference values within an array. I think I have figured out how to get what I want, but the code is really inefficient and takes several seconds in a small test array (n = 20). My production array will be around n = 1000. I suspect that there is a much more efficient way to get what I want.
Here is what I am conceptually trying to do:
array = (20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
newarray = (20-19, 19-18, 18-17, 17-16, 16-15, ... 2-1);
newarray2 = (20-18, 19-17, 18-16, 17-15, 16-14 ... 3-1);
newarray3 = (20-17, 19-16, 18-15, 17-14, ... 4-1);
differenceaverage = (sum of (20-19, 20-18, 20-17)/3, sum of (19-18, 19-17, 19-16)/3, etc.)
Here is the code that I used to generate the average:
$n=count($appArrayqb);
for($i = 1; $i<=($n-1); $i++){
$diff[]= $appArrayqb[$i-1]-$appArrayqb[$i];
}
for($i = 1; $i<=($n-2); $i++){
$diff2[]= $appArrayqb[$i-1]-$appArrayqb[$i+1];
}
for($i = 1; $i<=($n-3); $i++){
$diff3[]= $appArrayqb[$i-1]-$appArrayqb[$i+2];
}
$VOcomb = array($diff,$diff2,$diff3)
$sumVO = array_map ("sum", $VOcomb[0], $VOcomb[1], $VOcomb[2])
function sum ($arr1, $arr2, $arr3){
return($arr1+$arr2+$arr3);
}
$counts = array();
foreach($VOcomb as $item){
foreach($item as $k=>$v){
if(isset($item[$k])){
$counts[$k]++;
}
}
}
$VOarray=array($sumVO,$counts);
$VO = array_map("VO", $VOarray[0],$VOarray[1]);
function VO($arr1, $arr2) {
return($arr1/$arr2);
}
Incidentally, while the code works, I get an undefined offset notice when I run the count loop because it is trying to count values that don't exist in $item array. So I have three related questions:
1.) Is there a better way to calculate the differences?
2.) Is there a better way to get the count of the differences so I don't wind up with an undefined offset?
3.) Is the array_map function the best function to use to get the sums and averages?
Thanks!
Try this simplified code that seems to give the same result as yours:
It works by building the result array element by element, calculating the differences and averages as needed instead of creating arrays of differences and mapping over them.
// Calculate average differences between E(n) and E(n+1), E(n+2), and E(n+3)
// in an array
function diffaverages($appArrayqb) {
$n = count($appArrayqb);
$diffAvg = array();
for($i = 0; $i+1 < $n; $i++){
$diffsum = 0;
$count = 0;
for($j = 1; $j <= 3 && $i+$j < $n; $j++){
$diffsum += $appArrayqb[$i] - $appArrayqb[$i+$j];
$count++;
}
$diffAvg[] = $diffsum / $count;
}
return $diffAvg;
}

How to do a special shuffle function in php

I need a function that randomizes an array similar to what shuffle does, with the difference that each element has different chances.
For example, consider the following array:
$animals = array('elephant', 'dog', 'cat', 'mouse');
elephant has an higher chance of getting on the first index than dog. Dog has an higher chance than cat and so on. For example, in this particular example elephant could have a chance of 40% in getting in the 1st position, 30% of getting on the 2nd position, 20% on getting on 3rd and 10% getting on last.
So, after the shuffling, the first elements in the original array will be more likely (but not for sure) to be in the first positions and the last ones in the last positions.
Normal shuffle may be implemented just as
dropping items randomly at some range
picking them up from left to right
We can adjust dropping step, drop every element not into whole range, but at some sliding window. Let N would be amount of elements in array, window width would be w and we'll move it at each step by off. Then off*(N-1) + w would be total width of the range.
Here's a function, which distorts elements' positions, but not completely at random.
function weak_shuffle($a, $strength) {
$len = count($a);
if ($len <= 1) return $a;
$out = array();
$M = mt_getrandmax();
$w = round($M / ($strength + 1)); // width of the sliding window
$off = ($M - $w) / ($len - 1); // offset of that window for each step.
for ($i = 0; $i < $len; $i++) {
do {
$idx = intval($off * $i + mt_rand(0, $w));
} while(array_key_exists($idx, $out));
$out[$idx] = $a[$i];
}
ksort($out);
return array_values($out);
}
$strength = 0 ~normal shuffle.
$strength = 0.25 ~your desired result (40.5%, 25.5%, 22%, 12% for elephant)
$strength = 1 first item will never be after last one.
$strength >= 3 array is actually never shuffled
Playground for testing:
$animals = array( 'elephant', 'dog', 'cat', 'mouse' );
$pos = array(0,0,0,0);
for ($iter = 0; $iter < 100000; $iter++) {
$shuffled = weak_shuffle($animals, 0.25);
$idx = array_search('elephant', $shuffled);
$pos[$idx]++;
}
print_r($pos);
Try to use this algorithm:
$animals = [ 'elephant', 'dog', 'cat', 'mouse' ]; // you can add more animals here
$shuffled = [];
$count = count($animals);
foreach($animals as $chance => $animal) {
$priority = ceil(($count - $chance) * 100 / $count);
$shuffled = array_merge($shuffled, array_fill(0, $priority, $animal));
}
shuffle($shuffled);
$animals = array_unique($shuffled);
You have an array, let's say of n elements. The probability that the i'th element will go to the j'th position is P(i, j). If I understood well, the following formula holds:
(P(i1, j1) >= P(i2, j2)) <=> (|i1 - j1| <= |j1 - i1|)
Thus, you have a Galois connection between the distance in your array and the shuffle probability. You can use this Galois connection to implement your exact formula if you have one. If you don't have a formula, you can invent one, which will meet the criteria specified above. Good luck.

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