10

I need help to solve this formula ((n * 2) + 10) / (n + 1) = 3, preferably in PHP. (The numbers 2, 10 and 3 should be variables that can be changed.)

I'm able to solve this equation on paper quite easily. However, when I try to implement this in PHP, I'm not sure where to start. I've done several Google queries and searches on here and nothing seems to help. I'm missing the proper approach to deal with this problem.

Any tips and pointers would be great, and if you provide the exact code, please explain how you got to this result.

TRiG
  • 10,148
  • 7
  • 57
  • 107
xidew
  • 411
  • 1
  • 5
  • 12

5 Answers5

15

You're wanting to solve an equation, not implement it. There's a difference. Implementing the equation would be as simple as typing it in. You'd probably want to make it an equality operator (==) though.

Equation solvers are complicated, complicated things. I wouldn't try to make one when there are such good ones ( http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems ) lying around.

9

You can use http://pear.php.net/package/PHP_ParserGenerator/redirected to parse the math expressions into a syntax tree, then do the maths.

((n * 2) + 10) / (n + 1) = 3 would look like:

enter image description here

The idea is to bring on the right subtree (here ...) all the numbers, and on the left all the unknownws, just as you'd do on paper.

In the end you'll have:

  +
 / \
n  -7

which is 0. And there you have your solution, for any math expression (with one unknown variable).

I'll leave the algorithm to you.

Flavius
  • 13,566
  • 13
  • 80
  • 126
4
<?php

// ((x * n) + y)/(n + 1) = z)
// => n=(y-z)/(z-x)
function eq ($x=0,$y=0,$z=0)
{
    if ($z!=$x)
    {
        $n=($y-$z)/($z-$x);
    } else
    {
        $n='NAN';
    }
    return $n;
}

?>

(My algebra is old and flakey but I think this is right)

DaveyBoy
  • 2,928
  • 2
  • 17
  • 27
  • Your function works! Would you mind explaning what was your thought process when you were writing/thinking about it? – xidew Aug 31 '11 at 08:20
  • Your function is mathematically incorect. You're missing the case $y == $x && $z == $x. In such a case, the esemble `R - { 1 }` is solution of the equation. – Benjamin Crouzier Aug 31 '11 at 08:49
  • Also, if i call `eq(0, 0, 1);`, your function yields `-1`, yet `((x * n) + y)/(n + 1) = z)` gives `((0 * -1) + 0)/(-1 + 1) = 1)` which is impossible – Benjamin Crouzier Aug 31 '11 at 08:58
  • My get out clause is that my algebra is old and flakey and not something I use everyday. The main thing was to check for division by 0 (hence the check for Z<>X). My thinking behind the solution was to get the equation into the form of `x*n=c` (even if x is a fraction). Once it's in that form, the solution was a simple re-write of the equation into PHP – DaveyBoy Aug 31 '11 at 09:13
  • @pinouchon - obviously, more checks can be added for special cases. However, I'm a programmer and not a mathematician so my caveat is still valid - my algebra is old and flakey but I **think** this is right – DaveyBoy Aug 31 '11 at 09:21
  • @DaveWilsonLAMP check my answer where all special cases are handled. The drawbacks of not handling special cases is that in some cases, you answer is just **wrong**, eg `eq(0,0,0)`, `eq(1,1,1)`, `eq(0,0,1)`, `eq(1,1,2)`... – Benjamin Crouzier Aug 31 '11 at 09:29
  • @pinchoun - As I said **I am not a mathematician, I am a programmer**. As such, I drew on my algebra classes from 25 years ago to rearrange the original equation into something which will allow variables to be plugged in and an answer produced. The main thing that stood out was the "divide by 0" problem so I checked for that. Special cases did not occur to me as I did not run a whole load of numbers through the function to check for special cases - I don't have time to do that. My original answer included "I **think** this is right" so I was open to correction – DaveyBoy Aug 31 '11 at 10:02
  • I decided to give DaveWilsonLAMP the correct answer because he was the first who wrote the function even though it wasn't as complete as pinouchon, still was correct. @pinouchon have also a correct answer however, now I wish I could accept both of them... – xidew Aug 31 '11 at 10:32
  • @Flavius I actually voted up your answer. I didn't pick it because it was hard to understand at first but I understand what you were going for. What I learned from Dave and pinouchon answers is that the answer I was looking for was a simplified version of my equation. I learned a lot from all the answers here and I'm really grateful, unfortunately I can only pick one good answer... :-| – xidew Sep 09 '11 at 12:33
3

how about using brute-force??!?! might be slow and not exact:

$step = 0.00001;
$err = 0.1; //error margin
$start = 0;
$response = 3;

for($i = $start;$i <= 3;$i += $step){
   if((($i * 2) + 10) / ($i + 1) >= $response - $err){
       echo "the answer is $i";
   }
}

You could improove this answer.. on every loop you could calculate the distance between the current answer and the desired answer, and adjust the parameters acording to that..

This reminds me my old A.I. class =)

Good Luck

pleasedontbelong
  • 19,542
  • 12
  • 53
  • 77
  • 3
    That's a solution, but I'm looking for the proper way to solve it. Thanks for your answer though! – xidew Aug 31 '11 at 08:22
0

Here's how to solve that equation in C# with the Symbolism computer algebra library:

var n = new Symbol("n");

(((n * 2) + 10) / (n + 1) == 3)
    .IsolateVariable(n)
    .Disp();

The following is displayed on the console when that code is executed:

n == 7
dharmatech
  • 8,979
  • 8
  • 42
  • 88