The function for the primes is clear, so I omitted it.
$a=10;
$z=30;
for($prime = $a; $prime<$z; $prime++)
{ if
(Prim($prime) == TRUE)
{ echo $prime."<br/>";}}
Now I want to select the next term of the sequence as well, in order to perform an operation between the variable $prime and $next_prime, as long as the loop goes on - like for example:
$prime_gap=bcsub($next_prime, $prime);
Whatever solutions I find and I try, it's never the proper one. It's surely very simple but I am already desperate.
I would suggest you start by creating a next_prime() function. Like this, for example:
function next_prime($n) {
do {
$n++;
} while (!Prim($n));
return $n;
}
Then you can refactor your code quite easily:
$a=10;
$z=30;
for ($p1=next_prime($a),$p2=next_prime($p1); $p2<$z; $p1=$p2,$p2=next_prime($p2)) {
if (some_function($p1, $p2)) {
echo "I like $p1 and $p2\n";
}
}
The if I add in the for loop is not so nice, but if you want something simple and easy to understand, you can still use it (I switch the name from $prime & $next_prime to $prime & $previous_prime, I think it makes more sense)
$a=10;
$z=30;
$previous_prime = 0;
for($prime = $a; $prime<$z; $prime++)
{
if (Prim($prime) == TRUE)
{
echo $prime."<br/>";
if ($previous_prime == 0) {
$previous_prime = $prime
} else
{
$prime_gap = $prime - $previous_prime;
$previous_prime = $prime;
}
}
}
I am trying to validate 3 scenarios but something is wrong and the if statements are not being honored properly
Here are the scenarios I need to work:
If the string "2.5.4.15" exists in array then output "Extended Validation".
If the string "2.5.4.15" does NOT exist in array then output "Organization Validated".
If the string "id-at-organizationName" does NOT exist in array then output "Domain Validated".
I am getting incorrect results. For example, if the data I am parsing does contains "2.5.4.15" for some reason its returning "Domain Validated" ??
Here is my code:
if(isset($cert['tbsCertificate']['subject']['rdnSequence'])) {
$EV = array('2.5.4.15');
$org = array('id-at-organizationName');
$count = count($cert['tbsCertificate']['subject']['rdnSequence']);
for($i = 0; $i < $count; $i++) {
if(in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $EV)) {
$validation = "<tr><td>Validation</td><td>Extended Validation (EV)</td></tr>";
echo $validation;
break;
}
if(!in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $EV)) {
$validation = "<tr><td>Validation</td><td>Organization Validated (OV)</td></tr>";
echo $validation;
break;
}
if(!in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $org)) {
$validation = "<tr><td>Validation</td><td>Domain Validated (DV)</td></tr>";
echo $validation;
break;
}
}
}
-- UPDATE --
I removed the break; and I can see it's now returning multiple results before it gives our the correct one (highlighted in red the correct match).. but why is it returning the bogus response instead of just returning the correct response the first time ?
-- UPDATE 2 --
I think I understand the results I am getting, it seems to be outputting result for each iteration where the string is not found. Whereas what I want to do is return one response.
I think then because of this perhaps using a loop is not the answer. Is there a way to search the whole array for a string and output the result instead of looping through each array ?
I didn't understand why are you using 'array' to store single values, you can simple compare strings.
In case the field can match only to one option - you can use if..elseif or even better - switch.
Please notice that your $validation variable will always overwrite itself in every irritation. So, If you're looking for a specific row - you should mention it. If you're looking for one multi-result in the end, you need to store that data in another array.
In continuation to the chat, let me break the scenarios of the key's value:
If 2.5.4.15 exists in the array - return EV
If it (1) doesn't exist but 'id-at-organizationName' does - return
If it (1) doesn't exist and (2) also doesn't exist - return
For the first scenario I used break since if it exists we don't need to continue to check the rest of the array, also it's automatically means that the 2 other conditions could never exist. EDIT also added a break to the second scenario condition.
Here is my suggestion: (Please check it and share the output/problems in the chat until will accomplish to solve your problem)
if(isset($cert['tbsCertificate']['subject']['rdnSequence'])) {
$count = count($cert['tbsCertificate']['subject']['rdnSequence']);
for($i = 0; $i < $count; $i++) {
$value = $cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'];
if($value == "2.5.4.15") {
$output = "EV";
break;
} else {
if($value == "id-at-organizationName") {
$output = "OV";
break; //Edit 1
} else {
$output = "DV";
}
}
}
echo $output;
}
You echoes bad variables:
for($i = 0; $i < $count; $i++) {
if(in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $EV)) {
$validation = "<tr><td>Validation</td><td>Extended Validation (EV)</td></tr>";
echo $validation;
break;
}
if(!in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $EV)) {
$validation1 = "<tr><td>Validation</td><td>Organization Validated (OV)</td></tr>";
echo $validation1; // $validation1 instead of $validation
break;
}
if(!in_array($cert['tbsCertificate']['subject']['rdnSequence'][$i][0]['type'], $org)) {
$validation2 = "<tr><td>Validation</td><td>Domain Validated (DV)</td></tr>";
echo $validation2; // $validation2 instead of $validation
break;
}
}
The second thing is that for this task is better to use elseif instead of 3 ifs:
for () {
if () {
// validation
} elseif () {
// validation 1
} elseif () {
// validation 2
}
}
This is hypothetical code, assuming I have the following:
Let's say I have an array and it has lots of data, integers in this sample question, but it can ANY type of data that's already sorted in some fashion in regards to the if statements.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,...,9,9,9);
Let's say I have a for loop with numerous if else if statements, and those can have any criteria for doing something.
for($i=0; i<count($a); i++) {
// these if statements can be anything and may or may not be related with $a
if($a[$i] == 0 && $i < 10) {
// do something
}
else if($a[$i] == 1 && $i < 20) {
// do something
}
else if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
// and so on
}
Now the question, after the first if statement iterations are done, it's never used. Once the for loop starts using the next if statement, the previous if statement(s) don't need to be evaluated again. It can use the first if statement n amount of times and so on and so forth.
Is there a way to optimize it so it doesn't have to go through all the previous if else if statements as it's looping through the data? Mind, the data can be anything, and the if statements can be any variety of conditions.
Is there a paradigm shift, that I don't see, that is required on how this should be coded up to provide optimal performance?
You could leverage call_user_func_array. You would need to build a class that stored the methods to call to perform the statements. Consider a class like this:
class MyStatements {
public function If0($a, $i) {
if($a[$i] == 0 && $i < 10) {
// do something
}
}
public function If1($a, $i) {
if($a[$i] == 1 && $i < 20) {
// do something
}
}
}
you could then do something like this:
$stmts = new MyStatements();
for($i = 0; i < count($a); i++) {
call_user_func_array(array($stmts, 'If' . strval($i)), array($a, $i));
}
I think you are spinning your wheels.
If you have a lot of data, chances are, slowness is coming from the data source not the server-side calculations.
If you do anything, you should break up your data into chunks and run portions at-a-time. And you would only need to do this if you are noticing slow load-times or bad top-load on your server.
Asynchronous connections allow you to do this with ease, using ajax you can connect to your server, pull a limited chunk of data, process it, then after that displays in the client browser, run the next chunk. Anytime you use a Web site that queries large amounts of data (ie: facebook) it does it this way.
But again, don't over-think this. You really don't need to make your procedure more complicated. If you really want a gold-star you can make an object-oriented class that processes all this for you, but I will not get into that.
PHP uses something called "short-circuit evaluation," as many other modern languages do. This means once the boolean expression has been determined to be true or false, the remaining pieces of the expression will not be evaluated.
So, you could introduce new boolean values (maybe an array of them) that tracks if a piece of code has been executed already, and if it has been, set it to false. Then use this boolean as the first condition in the "if" expression. PHP will recognize that the value of this one is set to false, and ignore the rest of the clause. This is a pretty simple route, and would keep your code mostly structured the way it is now.
Break up your for statement into multiple for statements. For your example code:
for($i=0; i<10; i++) {
if($a[$i] == 0) {
//do something
}
}
for($i=0; i<20; i++) {
if($a[$i] == 1) {
//do something
}
}
for($i=0; $i<count($a); $i++) {
if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
}
//etc...
If you are using PHP 5.3+ then you can use anonymous functions.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$dispatch = array(
0=>function() { echo "0"; },
1=>function() { echo "1"; },
2=>function() { echo "2"; },
3=>function() { echo "3"; },
9=>function() { echo "9"; }
);
foreach ($a as $i)
{
$dispatch[$i]();
}
Before PHP 5.3 you would have to use a map to function names, but the bottom works in PHP 5.3+ as well.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
foreach ($a as $i)
{
$dispatch[$i]();
}
The above code is faster, but not completely efficient. To improve performance you would have to drop the key look up in the $dispatch array, and move forward each time the value of $a[#] changed. This assumes your $dispatch array matches the input array. You would only gain a performance improvement if the $dispatch array was very large.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
reset($dispatch);
$foo = (string)current($dispatch);
$last = 0;
foreach ($a as $i)
{
$foo();
if($i != $last)
{
$foo = (string)next($dispatch);
$last = $i;
}
}
That should be about as efficient as it can be.
I'm not sure how different this is from The Solution's, but I'd thought I'd throw it out there.
function func1 () {
echo "hi\n";
}
function func2 () {
echo "bye\n";
}
$functionList = array (
0 => "func1",
1 => "func2"
);
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$len = count($a);
for($i = 0; $i < $len; $i++) {
if (isset($functionList[$i])) {
call_user_func($functionList[$i]);
}
}
I set the keys of $functionList explicitly, since OP says they will not always be numeric. Perhaps the first 2-3 assignments could be wrapped into a class.
This verbose solution will prevent any if condition from being run after it has evaluated to false and will not iterate over the same $i value more than once except for when it transitions to the next loop.
for($i=0; i<count($a); i++) {
if($firstCondition) {
//do something
} else {
break;
}
}
for($i; i<count($a); i++) {
if($secondCondition) {
//do something
} else {
break;
}
}
I've created a loop where a variable is used to test if the current run-through of the loop is the first one. Its fairly simple:
$firstrun = true;
while(condition){
if($firstrun)
// Do this
else
// Do that
// Change $firstrun to false
}
I was just wondering (mostly out of curiosity because I'm it makes no real noticeable difference), when I need to change $firstrun to false, would be more efficient to test if the variable is true before assigning it to false or simply reassign it to false during each run-through?
Ex:
$firstrun = true;
while(condition){
if($firstrun)
// Do this
else
// Do that
if($firstrun)
$firstrun = false;
}
or simply
$firstrun = true;
while(condition){
if($firstrun)
// Do this
else
// Do that
$firstrun = false;
}
PS:
I guess this is a bad example also, because it would be most efficient to throw the reassignment of $firstrun in with the original condition, but as I said this is out of curiosity so I guess just pretend that is not an option for some reason.
PSS:
I was coding in PHP when this idea hit me, but I'm guessing the solution would be language agnostic. Just thought I would throw that in there in case it does for some reason matter.
So ultimately, which is faster, condition testing or variable assignment?
none of the above
$firstrun = true;
while(condition)
{
if($firstrun)
{
$firstrun = false;
}
else
{
}
}
reason I said so, because you are repetitively re-assign false to $firstrun, which you should just do at the first loop
condition test vs assignment which is faster?
for example you have shown, is the same (one execution cycle without some expensive call)
updated
I think condition testing will be slower, cause you might invoke series of subsequent action after that
This could be better, depending on what condition actually is:
if (condition) {
//execute first run code
while (condition) {
//execute subsequent run code
}
}
Given your example, you don't need the extra variable.
You don't even need the if statement if you know the code will always run at least once:
//execute first run code
while (condition) {
//execute subsequent run code
}
<?php
class Test
{
private $var = 156135135;
const SOMETHING = 156135135;
public function assign()
{
$this->var = self::SOMETHING;
}
public function conditionalAssign()
{
if ($this->var != self::SOMETHING) {
$this->var = SELF::SOMETHING;
}
}
}
$obj = new Test;
$start = microtime(true);
for ($i = 1; $i < 10000000; ++$i) {
$obj->assign();
}
echo round((microtime(true) - $start) * 1000, 2).' ms'.PHP_EOL;
$start = microtime(true);
for ($i = 1; $i < 10000000; ++$i) {
$obj->conditionalAssign();
}
echo round((microtime(true) - $start) * 1000, 2).' ms'.PHP_EOL;
conditionalAssign always faster when variable is integer, often faster when variable is boolean and almost equal, when variable is string.
I'm in PHP working on an Euler problem. I have this function so far:
<?php
$biggest = 0;
$counter = 1;
function test($i){
global $biggest;
global $counter;
if ($i == 1) {
echo "I'm done! Took me $biggest steps";
}
else {
if ($i%2 == 0) {
$counter = $counter + 1;
if ($counter>$biggest) {
$biggest = $counter;
}
test($i/2);
}
else {
$counter = $counter + 1;
if ($counter>$biggest) {
$biggest = $counter;
}
test(3*$i+1);
}
}
}
test(13);
?>
I have the problem mostly licked, but I can't seem to get back at the original input. The question is "When you have a number, if odd get 3n+1, when even, get n/2, do until returns 1. What starting value yields the most "steps" before you get to one?" I currently am returning the number of steps, but I keep resetting $i as I recurse, so I can't record what starting # yielded my $biggest number of steps.
How can I keep track of that number, but also not have it destroyed at the next instance of the loop? (I'll eventually wrap this in a for ($i=1, $i<1000000, $i++) loop)
Thanks!
A common approach is to pass the original argument through each time, so that when eventually you get to your base case, you still have it available. A primitive (and almost entirely unrelated example):
<?php
function fact($n) {
if($n == 1) return 1;
else return $n * fact($n - 1);
}
?>
This is an extremely basic implementation of the factorial function in PHP. Now say you wanted for whatever reason to have the initial value available in the final step: you'd build a wrapper function fact($n) that would call something like memory_fact($n, $initial):
<?php
function fact($n) {
return memory_fact($n, $n);
}
function memory_fact($n, $initial) {
if($n == 1) return 1;
else return $n * memory_fact($n - 1, $initial);
}
?>
This way, memory_fact always knows where it started.
It's easy, just pass it around as a parameter! Here's some python-ish pseudocode:
def func(start, arg):
if foo(arg):
return func(start, arg+1)
else:
return [start, arg]
You don't need the globals; globals are evil. Try returning something useful from test(). Also, you'll find the test() above wastes many cycles. Try using memoization.
Here's a memoization example for calculating Fibonacci numbers:
function fib($n) {
static $data = array(1, 1);
if (!isset($data[$n])) {
$data[$n] = fib($n-1) + fib($n-2);
}
return $data[$n];
}
Note that there are other time-efficent constant-space approaches to handle Fibonacci numbers (including one in O(log n) time), but the Collatz conjecture is a little trickier.