I have searched the internet in great detail and found many samples of PHP scripts that are addressing permutations. All these scripts are ok for permuting a few numbers and a few words here and there but when we get to perform some heavy stuff I can't execute the code.
Here is the essence of the thing we need and things I did.
I have to find all unique combinations of a range of numbers from 1 to 8.
I do this easily,, no problems there...
Then I have to permute each combination which should result with a crazy number results,, and then I have to perform string replacements on each result...
I know this is intense,,, and I do manage to get it done with numbers up to 6.
6 Executes pretty slow,, and 7 and 8 simply mess with the memory allocation on the machine.
My primary question is
Is there a way I can do permutations super fast? Preferably without affecting memory too badly... AND how fast can in PHP realistically a few million records be displayed (doing it in command line,,, browser doesn't matter here)
I don't know if this will be helpful, but i already made a script that generates the permutation of 10 numbers (0 -> 9) in lexicographic order, and it runs in ~60sec [Quadcore 2.7Ghz] and uses 512MB due to the array sizes ...
By mathematical calculations: 10! = 3628800 permutations in 60 sec, 8! = 40320 permutations, so it should run in (60 * 40320) / 3628800 = 0.67sec say 1 second !
You may need to change the code for a 8-number permutations!
PS: I don't know if the browser would handel the output of +3M numbers !
<?php
/* 0 - > 9 PERMUTATION SCRIPT */
ini_set('memory_limit', '512M');
ini_set('max_execution_time', '0');
$st = timer();
$permutations = array();
for($a=0;$a<=9;$a++){
for($b=0;$b<=9;$b++){
if($b != $a){
for($c=0;$c<=9;$c++){
if($c != $a && $c != $b){
for($d=0;$d<=9;$d++){
if($d != $a && $d != $b && $d != $c){
for($e=0;$e<=9;$e++){
if($e != $a && $e != $b && $e != $c && $e != $d){
for($f=0;$f<=9;$f++){
if($f != $a && $f != $b && $f != $c && $f != $d && $f != $e){
for($g=0;$g<=9;$g++){
if($g != $a && $g != $b && $g != $c && $g != $d && $g != $e && $g != $f){
for($h=0;$h<=9;$h++){
if($h != $a && $h != $b && $h != $c && $h != $d && $h != $e && $h != $f && $h != $g){
for($i=0;$i<=9;$i++){
if($i != $a && $i != $b && $i != $c && $i != $d && $i != $e && $i != $f && $i != $g && $i != $h){
for($j=0;$j<=9;$j++){
if($j != $a && $j != $b && $j != $c && $j != $d && $j != $e && $j != $f && $j != $g && $j != $h && $j != $i){
$permutations[] = $a.$b.$c.$d.$e.$f.$g.$h.$i.$j;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
echo count($permutations);
$et = timer();
$time = $et - $st;
echo "<br/>in : ".$time." seconds.";
function timer(){
list($usec, $sec) = explode(" ", microtime());
return((float)$usec + (float)$sec);
}
?>
EDIT: 1->8 permutation script in: ~0.43 seconds.
<?php
$permutations = array();
for($a=1;$a<=8;$a++){
for($b=1;$b<=8;$b++){
if($b != $a){
for($c=1;$c<=8;$c++){
if($c != $a && $c != $b){
for($d=1;$d<=8;$d++){
if($d != $a && $d != $b && $d != $c){
for($e=1;$e<=8;$e++){
if($e != $a && $e != $b && $e != $c && $e != $d){
for($f=1;$f<=8;$f++){
if($f != $a && $f != $b && $f != $c && $f != $d && $f != $e){
for($g=1;$g<=8;$g++){
if($g != $a && $g != $b && $g != $c && $g != $d && $g != $e && $g != $f){
for($h=1;$h<=8;$h++){
if($h != $a && $h != $b && $h != $c && $h != $d && $h != $e && $h != $f && $h != $g){
$permutations[] = $a.$b.$c.$d.$e.$f.$g.$h;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
echo count($permutations);
?>
Related
I have three condition/variable combination e.g. below called amounts:
$a = 15000; $b = 10000; $c = 5000;
or
$a = 10000; $b = 15000; $c = 0;
or
$a = 12000; $b = 0; $c = 15000;
etc.
At least each $a or $b or $c above is not 0 (zero).
If the amount of each not 0 (zero) it have its own associated array e.g. if $b == 0 then $b_array will not set/created, assume all is not 0(zero) then below arrays are created:
$a_array = array('id'=>1);
$b_array = array('id'=>2);
$c_array = array('id'=>3);
If $a / $b / $c is not 0 (zero) then if $b or $c not zero it needs to be linked to $a or $b (if not zero) as below:
if($a != 0 && $b != 0 && $c != 0){
$b_array['id_link'] = $a_array['id'];
$c_array['id_link'] = $a_array['id'];
} elseif ($a != 0 && $b != 0 && $c == 0){
$b_array['id_link'] = $a_array['id'];
} elseif ($a != 0 && $b == 0 && $c != 0){
$c_array['id_link'] = $a_array['id'];
} elseif ($a == 0 && $b != 0 && $c != 0){
$c_array['id_link'] = $b_array['id'];
}
The result for conditional statement above seems correct as you can check at the php sandbox
Is there any better idea for the conditional code and is there a missing condition (error handling). Any idea or solutions is greatly appreciated. Thanks!!
If I understand your question correctly, instead of checking for every combination possible, just get the first non zero number and assign it's id as id_link to all of them like below:
<?php
$id_link = -1;
if($a !== 0){
$id_link = $a_array['id'];
}else if($b !== 0){
$id_link = $b_array['id'];
}else if($c !== 0){
$id_link = $c_array['id'];
}
$a_array['id_link'] = ($b_array['id_link'] = ($c_array['id_link'] = $id_link));
Online Demo
(The brackets in the expression are added just for readability since they are redundant in case of PHP)
Update:
If you wish to leave the array with it's corresponding variable without the id_link key, then you can just use another 3 if conditions to take care of it.
<?php
$id_link = -1;
if($a !== 0){
$id_link = $a_array['id'];
}else if($b !== 0){
$id_link = $b_array['id'];
}else if($c !== 0){
$id_link = $c_array['id'];
}
if($a !== 0){
$a_array['id_link'] = $id_link;
}
if($b !== 0){
$b_array['id_link'] = $id_link;
}
if($c !== 0){
$c_array['id_link'] = $id_link;
}
Online Demo
How can I optimize this if-statement?
if ($min && $max && $value && ($min <= $max) && ($min <= $value) && ($value <= $max)) {
// do anything
}
What it should do:
I got three values (min, max and value). First of all, all values should be != 0. Second, min <= value <= max.
Valid:
min = 1; max = 3; value = 2;
min = 2; max = 2; value = 2;
this:
if ( 0 < $min && $min <= $value && $value <= $max ){
echo 'good';
}
The answer is:
if(isset($min , $max , $value ) && ($min <= $value) && ($value <= $max)){
//Insert your code here
}
I think this prevents any value from being a 0 and makes sure value is inside the min and max range.
if ( ( $min > 0 && $max >= $min ) && ( $value >= $min && $value <= $max ) ) {
echo "Good";
} else {
echo "Bad";
}
I have a problem with calculating the standard deviation in php. But it's generating the wrong result.
e.g. I am getting as result for (4+4+4+4+4+4) = 1.40 instead of 0.
Please help.
function std_dev ($attr, $test1,$test2,$test3,$test4,$test5,$test6) {
//$items = array($test1->$attr,$test2->$attr,$test3->$attr,$test4->$attr,$test5->$attr,$test6->$attr);
$items[] = array();
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
if (isset($test2) && $test2->$attr != 9 && $test2->$attr != 0) {
$items[] = $test2->$attr;
}
if (isset($test3) && $test3->$attr != 9 && $test3->$attr != 0) {
$items[] = $test3->$attr;
}
if (isset($test4) && $test4->$attr != 9 && $test4->$attr != 0) {
$items[] = $test4->$attr;
}
if (isset($test5) && $test5->$attr != 9 && $test5->$attr != 0) {
$items[] = $test5->$attr;
}
if (isset($test6) && $test6->$attr != 9 && $test6->$attr != 0) {
$items[] = $test6->$attr;
}
$sample_square[] = array();
$item_count = count($items);
for ($current = 1; $item_count > $current; ++$current) $sample_square[$current] = pow($items[$current], 2);
$standard_deviation = sqrt(array_sum($sample_square) / $item_count - pow((array_sum($items) / $item_count), 2));
return round($standard_deviation,2);
}
$items = array();
$sample_square = array();
no [] when you define those variables as arrays.
for ($current = 0; $item_count > $current; ++$current)
start from 0 not 1 if you want to iterate over all the elements (otherwise you'll miss item at index 0)
Wondering what this is for...
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
and how you pass input values to the function. This may also cause wrong result...
if i have statement:
$a = 1;
$b = 2;
$c = 3;
if($a == 1 && $b == 2 && $c == 3)
{
echo 'correct';
}
else
{
echo 'what variable's weren't matched';
}
Is there any way of knowing what didn't watch instead of writing everything separately?
Cheers!
No. Your expression was turned into a boolean, so apart from checking the equality(s) again you cannot find out which triggered the "false".
You need to test each individually, but you could do something like this:
$a = 1;
$b = 2;
$c = 3;
$a_matched = $a == 1;
$b_matched = $b == 1;
$c_matched = $c == 1;
if($a_matched && $b_matched && $c_matched)
{
echo 'correct';
}
else
{
if (!$a_matched) echo 'a did not match!';
if (!$b_matched) echo 'b did not match!';
if (!$c_matched) echo 'c did not match!';
}
but that's less clear than just:
$a = 1;
$b = 2;
$c = 3;
if($a == 1 && $b == 2 && $c == 3)
{
echo 'correct';
}
else
{
if (!$a == 1) echo 'a did not match!';
if (!$b == 2) echo 'c did not match!';
if (!$c == 3) echo 'b did not match!';
}
Actually, heh, I take back my comment. You can rely on the boolean short-circuiting to set a variable indicating the last part of the conditional which was true:
if (($x = 'a') && $a == 1 && ($x = 'b') && $b == 2 && ($x = 'c') && $c == 3) {
echo "correct\n";
} else {
echo "$x is wrong\n";
}
Note, I would never write this in production code because it's goofy and very hard to understand what's supposed to be going on. But fun to fiddle with, at least.
Nope! That's not possible. You can make life a lot simpler by using arrays, though:
$results = array(1, 2, 4);
$expected = array(1, 2, 3);
$count = count($results);
$wrong = array();
for($i = 0; $i < $count; $i++) {
if($results[$i] !== $expected[$i]) {
$wrong[] = $i;
}
}
if(count($wrong) > 0) {
echo "There were wrong ones. They were at positions: " . implode(', ', $wrong);
} else {
echo "All good!";
}
For example.
I'm trying to rewrite a pascal program to PHP, and don't understand what this part of pascal function do:
while (u[3] <> 1) and (u[3]<>0) and (v[3]<>0)do
begin
q:=u[3] div v[3];
for i:=1 to 3 do
begin
t:=u[i]-v[i]*q;
u[i]:=v[i];
v[i]:=t;
{writeln('u',i,'=',u[i],' v',i,'=',v[i]); }
end;
end;
if u[1]<0 then u[1]:=n+u[1];
rae:=u[1];
Please help to rewrite it to PHP.
Thanks.
A very literal translation of that code, should be this one:
while ($u[3] != 1 && $u[3] != 0 && $v[3] != 1 )
{
$q = floor($u[3] / $v[3]);
for ($i = 1; $i <= 3; $i++)
{
$t = $u[$i] - $v[$i] * $q;
$u[$i] = $v[$i];
$v[$i] = $t;
//writeln('u',i,'=',u[i],' v',i,'=',v[i]);
}
}
if ($u[1] < 0 )
$u1] = $n + $u[1];
$rae = $u[1];
Of course, u and v are arrays. Sorry for not giving any more info, but it's been like 10 years since Pascal and I last saw each other, but we had a profound romance for a long time, since I feel inlove for to hotties(C# and PHP) :)
while ($u[3] != 1) && ($u[3] != 0) && ($v[3] != 0) {
$q = floor($u[3] / $v[3]);
for ($i = 1; $i <= 3; $i++) {
$t = $u[$i] - $v[$i] * $q;
$u[$i] = $v[$i];
$v[$i] = $t;
echo "u$i={$u[$i]} v$i={$v[$i]}\n";
}
}
if ($u[1] < 0) {
$u[1] = $n + $u[1];
}
$rae = $u[1];
2 small corrections to David's code:
while ($u[3] != 1 && $u[3] != 0 && $v[3] != 1 )
should be
while ($u[3] != 1 && $u[3] != 0 && $v[3] != 0 )
and
for ($i = 1; $i < 3; $i++)
i never reaches the value of 3
for ($i = 1; $i <= 3; $i++)
May be the Writeln can be translated to
echo 'u'.$i.'='.$u[$i].' v'.$i.'='.$v[$i];
When you do the translation of arrays, take into account that arrays in php uses 0 as the first index.
$u= array( 3, 5, 22 )
echo u[1]; // prints 5
while($u[3] != 1 && $u[3] != 0 && $v[3] != 0)
{
$q = ($u[3] - ($u[3] % $v[3]) ) / $v[3]; //just the same as floor($u[3]/$v[3]), but i want to use % here :)
for ($i = 1; $i <= 3; $i++)
{
$t = $u[$i] - $v[$i]*$q;
$u[$i] = $v[$i];
$v[$i] = $t;
echo '<br />u'.$i.'='.$u[$i].' v'.$i.'='.$v[$i];
}
}
if ($u[1] < 0) $u[1] = $n + $u[1];
$rae = $u[1];
I dont know pascal But i have tried :)
while ($u[3]!=1 && $u[3]!=0 && $v[3]!=0) [
$q=floor($u[3]/ $v[3]);
for ($i=1;$i<3;$i++) {
$t=$u[$i]-$v[$i]*$q;
$u[$i]=$v[$i];
$v[$i]=$t;
echo "u".$i."=".$u[$i]."v".$i."=".$v[$i];
}
if ($u[1]<0) {
$u[1]=$n+$u[1];
}
$rae=$u[1];
In php variable Name Start With $
No Begin End used here in php only braces :)