Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hello i would like the loop below to generate a random prime number below 1000. But only generate 1 with the variable $i and the variable $finish should allow the while loop to stop after the first prime number is found and if the number is not prime it should generate a new $i variable randomly and check if its a prime number again until the first prime number is found.
<html>
<body>
<?php
$finish="a";
while($finish = "a") {
$i = (mt_rand(0,999));
$counter = 0;
for($j = 1; $j <= $i; $j++) { //all divisible factors
if($i % $j == 0) {
$counter++;
}
//prime requires 2 rules ( divisible by 1 and divisible by itself)
if($counter == 2){
print $i." is Prime <br/>";
$finish = "b";
}
}
}
?>
</body>
</html>
how can i modify this so that it will stop the code after the first prime number below 1000 is found?
The problem is $finish="a" - you are assigning the string a (which is truthy) to $finish. So this loop will run forever (as the condition is always true).
You are setting flags as string and ints while boolean here should suffice. In addition to that, once a divisor >= 2 is found you can stop the for() loop. If you introduce a helper function it becomes even more readable.
function isPrime($number) {
$max = $number;
for ($i=2; $i < $max; $i++) {
if ($number % $i == 0)
return false;
}
return true;
}
do {
$i = mt_rand(100, 9999);
} while ( ! isPrime($i) );
var_dump($i);
See it work here. I'm not too sure but sqrt($number) should suffice as $max and make the loop shorter -> the script faster.
To break out of your 2 loops when the condition is matched, you can use break 2:
if($counter == 2){
print $i." is Prime <br/>";
$finish = "b";
break 2;
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How would you go about answering a question like this? I know I would have to use a loop, but my current answer won't allow me to go over an input of about 5 which is incredibly inefficient. I'm finding nested loops a little daunting.
Given the triangle of consecutive odd numbers:
1
3 5
7 9 11
...
Calculate the row sums of this triangle from the row index (starting at index 1)
rowSumOddNumbers(1); // 1
rowSumOddNumbers(2); // 3 + 5 = 8
Disclaimer - this is not a test questions. Just one of the practice ones I'm struggling to get my head around.
Since posting this I have found a working answer (three hours later...)
Working code:
function rowSumOddNum($n) {
$start = ($n *($n - 1)) + 1;
$sum = 0;
$step = $start +($n*2);
for($a=$start;$a<$step;$a++){
if($a % 2 !== 0){
$sum = $sum + $a;
}
} echo $sum;
}
This was the original code I was working with that kept crashing out saying it didn't have enough memory. Very inefficient I believe.
function rowSumOddNumbers($n) {
$len = $n + ($n*1);
$array = [];
for ($i = 1; $i <= $len; $i+2) {
if ($i % 2 == 1) {
$array[] = $i;
}
}
$count = 0;
$answer = 0;
for ($row = 1; $row < $n; $row++) {
$count = $count + $row;
}
$length = $count + $n;
for ($a = $count; $a <$length; $a++) {
$answer = $answer + $array[$a];
}
echo $answer;
}
I liked the challenge, so here it is.
This should do the job no matter how big the triangle is.
<?php
$triangle = array(1,5,11,9,7,3);
$u = 1;
$results = array();
$sumrow =0;
for($i=0; $i<=count($triangle); $i++){
if($i == count($triangle)){
$sumrow += $triangle[0]; // for the last row add the first number of array
}else{
$sumrow += $triangle[$i];
}
if(is_int($u/3)){ // for every third number store results and use the same number again
$i--;
$u = 1;
array_push($results, $sumrow);
$sumrow = 0;
}else{
$u++;
}
}
echo json_encode($results);
?>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want to make row of number jumps, example I have $a = 1 and $b = 2. then I want loop $a and $b and the result is $a = '1', '5', '9', '13', '17' and $b = '2', '6', '10', '14', '18' . How to make it?
You might want to add some context as to me it looks like a generic PHP question, but you also added the codeigniter tag which looks like there is more to it than you wrote.
If I understand you correctly, you start with two numbers and want to generate an list (array) for each of those numbers. Reusing $a and $b for the results might not be a good idea. So I suggest you save the result to a different variable:
// initialize A
$a=1;
$a_result=[];
// initialize B
$b=2;
$b_result=[];
// set the jump size
$jump_size=4;
// loop 5 jumps
for($i=0; $i<5; $i++) {
// add new elements to the result arrays
$a_result[] = $a + $jump_size * $i;
$b_result[] = $b + $jump_size * $i;
}
// print the results
print_r($a_result);
print_r($b_result);
If you have more than just two numbers to start from, you might want to put those in an array too (as well as the result arrays).
You can check odd or even number using modulo, and skip next number.
See below example.
See Running Example
$a = 1;
$b = 2;
for($i = $a; $i <= 20; $i++){
if($i > 1 && $i % 2){
$i = $i + 2;
}
if($i % 2 == 1) {
echo $i;
}
}
echo " b=> ";
for($i = $b; $i <= 20; $i++){
if($i > 1 && $i % 2){
$i = $i + 2;
}
if($i % 2 == 0) {
echo $i;
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I was in a job interview and was asked to solve FizzBuzz with PHP.
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
I never heard of FizzBuzz before but here is how I solved it because I didn't know modulo or how to use it.:
for ($i = 1; $i <= 100; $i++){
if($i / 3 == round($i / 3) && $i / 5 == round($i / 5)){
echo $i . " is FizzBuzz<br />";
}
else if($i / 3 == round($i / 3)){
echo $i . " is Fizz<br />";
}
else if($i / 5 == round($i / 5)){
echo $i . " is Buzz<br />";
}
else {
echo $i."<br />";
}
}
I googled and didn't find any solution with round and that got me thinking that maybe there is something wrong with it, this is one of the solutions I found that is close to mine:
for ($i = 1; $i <= 100; $i++){
if($i % 3 == 0 && $i % 5 ==0){
echo "FizzBuzz<br />";
}
else if($i % 3 == 0){
echo "Fizz<br />";
}
else if($i % 5 == 0){
echo "Buzz<br />";
}
else {
echo $i."<br />";
}
}
My code is working fine but is there anything wrong with it that I don't see?
Actually they are testing how you will solve such simple task. It should be increadibly optimized, the code shouldbe clean and easy readable.
Your version of code is not good.
The version you've found in the internet is better, but it's not ideal from the point of the optimization.
Try to think how to get the goal with less actions.
Some tips:
do not use functions (such as range) for this task - it will only slow down the script execution time
use operator "for" for this task, do not use any other (while, do-while, foreach), because operator "for" the best fits in this case (you know how many iterations you need).
do not use round function, use modulus operator "%", because any function works slower than any operator
in the result you need to get code, in which the number of operations will be the least as possible (the number of "if" statements, the number of operators like "==" or "%"
Use 15 instead of % 3 && % 5 - less calculations - faster execution time.
My example of code:
for ($i = 1; $i <= 100; $i++) {
if ($i % 15 == 0) {
echo 'FizzBuzz<br>';
} elseif ($i % 3 == 0) {
echo 'Fizz<br>';
} elseif ($i % 5 == 0) {
echo 'Buzz<br>';
} else {
echo $i . '<br>';
}
}
Code style and lack of optimization gives impression of a newbie to the interviewer. My tips are:
Follow PSR-2
Never use else (restructure, use early returns/continues)
Always try to reduce the number of ifs (code complexity)
Use "identical" operators for comparison when dealing with integers and nulls (and any other type)
Do not use <br/> when HTML is never mentioned
Try to keep maintainability:
Extract match calculations in variables/functions, so they can be easily changed
Do not overcomplicate.
Try to optimize mathematically:
Use %15 instead of %3 and %5 check
You can also skip the above at all (check for %15), as you already have calculated that. Boolean operations are much faster.
Try not to calculate something twice.
IMHO, to follow all good practices your code should look like this:
for ($i = 1; $i <= 100; $i++) {
$isFizz = (0 === $i % 3);
$isBuzz = (0 === $i % 5);
if (!$isFizz && !$isBuzz) {
echo $i . PHP_EOL;
continue;
}
if ($isFizz) {
echo 'Fizz';
}
if ($isBuzz) {
echo 'Buzz';
}
echo PHP_EOL;
}
Test
There is yet another tricky solution
for ($i = 1; $i <= 100; $i++) {
switch ($i % 15) {
case 3:
case 6:
case 9:
echo 'Fizz';
break;
case 5:
case 10:
echo 'Buzz';
break;
case 0:
echo 'FizzBuzz';
break;
default:
echo $i;
break;
}
echo PHP_EOL;
}
if you read carefully it says "instead".
this is another short and clean solution of the FizzBuzz problem :
foreach (range(1, 100) as $number) {
if(0 !== $number % 3 && 0 !== $number % 5) {
echo $number.'<br>';
continue;
}
if(0 === $number % 3) {
echo 'Fizz';
}
if(0 === $number % 5) {
echo 'Buzz';
}
echo '<br>';
}
the output is :
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
This question already has answers here:
A formula to find prime numbers in a loop
(22 answers)
Closed 7 years ago.
I'm teaching my wife to code, so we made a simple prime-number detector.
We came up with this, but I'm wondering if there's a better / neater way. I particularly don't like the 0/1 switch for displaying the end statement.
//get n from URL
$n = $_GET['n'];
$j=2;
$prime=1;
while ($j<=($n/2)){
if (is_int($n/$j)){ $prime=0;
break;
}
$j++;
}
if ($prime==1) {echo "Yes! $n is a prime number";}
else {echo "No, $n is not a prime number";}
As far as a 'neater' way to display the end statement, you could just tidy it up with:
echo ($prime) ? "Yes! $n is a prime number" : "No, $n is not a prime number";
Also for readability you could use boolean true/false instead of 1 and 0's but that's really just your preference.
There is always the neat and newbie friendly regular expressions way of finding prime numbers:
$n = $_GET['n'];
echo "$n is ", preg_match('/^1?$|^(11+?)\1+$/', str_repeat('1', $n))
? "not " : "", "a prime number", PHP_EOL;
No seriously, what I would suggest is that you tidy up your code a bit, so it gets easier to read:
Remove unnecessary parentheses
Rename $prime to $isPrime
Change $j++ into $j = $j + 1
Add a quick check on 0, 1 which are not prime numbers
Like so:
// Get parameter 'n' from URL
$n = $_GET['n'];
if ($n <= 1) {
$isPrime = false;
}
else {
$isPrime = true;
$j = 2;
while ($j <= $n / 2) {
if (is_int($n / $j)) {
$isPrime = false;
break;
}
$j = $j + 1;
}
}
if ($isPrime) {
echo "$n is a prime number";
}
else {
echo "$n is not a prime number";
}
function find_highest_prime_factor($n)
{
for ($i = 2; $i <= $n; $i++)
{
if (bcmod($n, $i) == 0) //its a factor
{
return max($i, find_highest_prime_factor(bcdiv($n,$i)));
}
}
if ($i == $n)
{
return $n; //it's prime if it made it through that loop
}
}
UPDATE: This is the correct answer, my bad!
Get rid of the final if statement otherwise if $i!=sqrt($n) because sqrt($n) is not an integer you have an undefined return value
function find_highest_prime_factor($n){
for ($i = 2; $i <= sqrt($n); $i++) //sqrt(n) is the upperbound
{
if (bcmod($n, $i) == 0) //its a factor
{
return max($i, find_highest_prime_factor(bcdiv($n,$i)));
}
}
return $n; //it's prime if it made it through that loop
}
Line 11 should be:
if ($i == ceil(sqrt($n)))
Starting at 2 and stepping by 1 is inefficient. At least check 2 separately and then loop from 3 stepping 2 each time. Using a 2-4 wheel would be even faster.
When you recurse your code starts again at trial factor 2. It would be better to pass a second parameter holding the factor you have reached so far. Then the recursion wouldn't have go back over old factors that have already been tested.