开发者

PHP - Do (and echo) operation only when remainder from is 0 - Going into infinite loop

Let me start by the end and the actual question:

I'm trying to write a PHP script that from two random numbers $x and $y will only we outputted and resolved when modulo == 0 (it should always echo a valid function)

What do I mean:

The script echos:

4 / 2 => GOOD!

The script echos:

4 / 3 => BAD!

NOTHING => BAD!


I'll try to guide you through my reasoning but be warned:

I'm a newbie so: I learn something, up the ante, and try to apply it conveniently.


First I generate the random numbers, easy:

$x = mt_rand(1,10);
$y = mt_rand(1,10);

Now I say, I have two possibilities after division, remainder 0 or not 0, so an if() statement looks like a good idea, so I do:

if($x % $y == 0){

echo $x . "/" . $y;

}else{

echo "The remainder is not 0";

}

This works as expected except of course, I always want to generate this remainder is not 0 divisions.

So my approach was the following, why not use user generated functions (never used the before but could come in handy) so, if I know this works just fine:

<?php
 
function hello(){   
      echo "Hello!";  
}
 
hello();
?>

Wh开发者_Python百科y not up the ante as I said before and use it, so I mix the up:

<?php
$x = mt_rand(1,10);
$y = mt_rand(1,10);
 
function foo(){
 
if($x % $y == 0){
 
echo $x . "/" . $y;
 
}else{
        
foo();  
        
}
 
}
 
?>

It doesn't work, I get a blank screen.

What was I expecting from this script:

  • Create a function with an if() statement on it
  • If the remainder is 0, great, echo.
  • else, start all over, again and again, till you get a division with no remainder.

This does't work.

So I basically ask, what I am doing wrong? What is wrong with the line of though behind this?

Can this work with a subtle change?


To experienced coders, I know you could all make a script that does this (but has nothing to do with mine) using MS PAINT as an IDE, BUT:

I have no interest in the code itself since this is ONLY for learning purposes.

This is not the first time it has happened to me, I keep hitting the wall with infinite loops VERY often, so the slighter the change (and the bigger the explanation) the better, and will be very much appreciated.

Thanks in advance!


Now that finish I've just realized the problem might not even be a infinite loop, even if it's not the question still stands, what do you think think of my approach? (of course I will also edit and remove the infinite loop from the question)


It looks to me like you only set $x and $y once.

That means they won't change when you recursively call foo(). I'd start by trying something like this:

<?php
    function foo() {
        $x = mt_rand(1,10);
        $y = mt_rand(1,10);
        if ($x % $y == 0) {
            echo $x . "/" . $y;
        } else {
            $x = mt_rand(1,10);    # need to recalculate them here.
            $y = mt_rand(1,10);
            foo();  
        }
    }
?>

I'd check that code though. I know PHP about as well as I know Aramaic :-) My analysis is based more on general language knowledge, so the syntax may be bogus.

Of course, you may want to think about avoiding recursion altogether in this case. There's really no need for it. Recursion is fine when it makes your code more elegant but I don't believe that's the case here. I'd give something like this a shot:

<?php
    function foo() {
        $x = mt_rand(1,10);
        $y = mt_rand(1,10);
        while ($x % $y != 0) {
            $x = mt_rand(1,10);
            $y = mt_rand(1,10);
        }
        echo $x . "/" . $y;
    }
?>


Alright, let's start with the basics.

The reason why your application isn't displaying anything is because you haven't told it to. You've defined a function which will display something, but you've never actually called it.

Basically, you need to do this:

function foo() {
  // foo logic
}


foo();

Notice how the call to foo is made outside of the function itself, in the mainline logic of the application.

Next, you need to move your calls to mt_rand() to be inside your foo() function, so that new random numbers will be generated on every call.

Finally, you don't need to make calls to foo() from within foo(). Doing this is allowed, and is something called "recursion", but it's really not needed here. What you should do is set your function up so that it returns a boolean (i.e. true/false) value when the function finishes, letting you know that it worked. You can then setup a while loop to repeatedly execute the function until it completes properly.

Here is an example:

function foo() {
  //define the random values
  $x = mt_rand(1,10);
  $y = mt_rand(1,10);

  //if they match, echo the statement and return true so the loop ends
  //otherwise, return false so the loop repeats
  if (($x % $y) == 0) {
    echo $x . "/" . $y;
    return true;
  } else {
    return false;
  }
}

//we're now *outside* of the function, and in mainline logic

//setup a variable to hold the return value of the function
//initialize it to false so that the first loop executes
$foundEquation = false;


//execute the function in a loop until we find
//the right equation
while(!$foundEquation) { 
  $foundEquation = foo();
}

Does that answer your question? Let me know if you have any trouble understanding what's happening here. I'm happy to clarify anything about this code.


Your problem is that you're not redeclaring $x and $y. Hypothetically, this should go into infinite recursion. If you want to do this recursively, you're going to have to define $x and $y in your foo() function. Make sure the variables are declared outside and before your if() statement.

Good luck!
Dennis M.


In the "It doesn't work" link that you posted, you're not calling the function foo().

A couple of notes:

  • y may be zero so you might get a "divide by zero" error.
  • You are using recursion and a majority of the time your code would go into the else case. If your nesting depth gets large, you might encounter a stack overflow.


Paxdiablo is on the right track but this is what you probably want:

<?php
    function foo() {
        do
        {
            $x = mt_rand(1,10);
            $y = mt_rand(1,10);
        }
        while ($x % $y != 0);

        echo $x . "/" . $y;
    }
?>

This will loop executing the code inside the do { } while until the while condition to false. The difference between a while and a do while is that the code is executed before the condition is checked.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜