Advertisement
Guest User

Untitled

a guest
Jun 27th, 2014
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 2.88 KB | None | 0 0
  1. <?php
  2.  
  3.  
  4. /**
  5.  * Return answer, operator precedence must be retained. / * - + is the order.
  6.  * @param unknown $s
  7.  */
  8. function calc($sum){
  9.  
  10.     // No requirement for handling parenthesis here,
  11.     // but I'll do it anyway because I like recursion :)
  12.     $sIX=0;
  13.     $moreBrackets=true;
  14.     // Always work out sums in brackets first, from deepest to most shallow
  15.     while($moreBrackets){
  16.         $l=strlen($sum);
  17.         $moreBrackets=false;
  18.         for($n=0;$n<$l;$n++){
  19.             if($sum{$n}=='('){
  20.                 $moreBrackets=true;
  21.                 $sIX=$n;
  22.             }
  23.             if($sum{$n}==')'){
  24.                 if(!$moreBrackets){
  25.                     return "Error, no opening bracket for closing bracket!";
  26.                 }
  27.                 // Could obviously combine these 3 lines into 1,
  28.                 // but I'll pay lip service to readability...
  29.                 $subSum=substr($sum,$sIX+1,$n-$sIX-1);
  30.                 $newSum=substr($sum,0,$sIX).calc($subSum).substr($sum,$n+1);
  31.                 $sum=$newSum;
  32.                 break;
  33.             }
  34.         }
  35.     }
  36.    
  37.     $ops="/*-+";
  38.     $result=0;
  39.     $gotOperator=false;
  40.     if($sum{0}=='-')
  41.         $sum{0}='N';
  42.    
  43.     for($n=0;$n<strlen($ops);$n++)
  44.         $sum=str_replace($ops{$n}.'-',$ops{$n}."N",$sum);
  45.  
  46.     for($n=0;$n<strlen($ops);$n++){
  47.         $op=$ops{$n};
  48.         $ix=1;
  49.         while($ix!==false){
  50.             $ix=strpos($sum,$op);
  51.             $len=strlen($sum);
  52.             if($ix!==false){
  53.                 $gotOperator=true;
  54.                 if($ix==0||$ix==$len-1){
  55.                     return "Error, operator not enclosed by digits";
  56.                 }
  57.                 $s=$ix-1;
  58.                 $e=$ix+1;
  59.                
  60.                 // Find start of lhs value
  61.                 while($s>-1 && (($sum{$s}>='0' && $sum{$s}<='9') || ($sum{$s}=='.' || $sum{$s}=='N')))
  62.                     --$s;
  63.                 // Find end of rhs value
  64.                 while($e<$len && (($sum{$e}>='0' && $sum{$e}<='9') || ($sum{$e}=='.' || $sum{$e}=='N')))
  65.                     ++$e;
  66.                 ++$s;
  67.                 --$e;
  68.                
  69.                 // Check for negative values and decimals with no leading digit
  70.                 $v0=substr($sum,$s,$ix-$s);
  71.                 if($v0{0}=='.')
  72.                     $v0='0'.$v0;
  73.                 else if($v0{0}=='N')
  74.                     $v0{0}='-';
  75.                 $v1=substr($sum,$ix+1,$e-$ix);
  76.                 if($v1{0}=='.')
  77.                     $v1='0'.$v1;
  78.                 else if($v1{0}=='N')
  79.                     $v1{0}='-';
  80.                
  81.                 switch($op){
  82.                     case '/':
  83.                         $result=$v0/$v1;
  84.                         break;
  85.                     case '*':
  86.                         $result=$v0*$v1;
  87.                         break;
  88.                     case '-':
  89.                         $result=$v0-$v1;
  90.                         break;
  91.                     case '+':
  92.                         $result=$v0+$v1;
  93.                         break;
  94.                 }
  95.                 if($result<0)
  96.                     $result='N'.(-$result);
  97.                 $newSum=substr($sum,0,$s).$result.substr($sum,$ix+1+($e-$ix));
  98.                 $sum=$newSum;
  99.             }
  100.         }
  101.     }
  102.     if($sum{0}=='N')
  103.         $sum{0}='-';
  104.     return $sum;
  105. }
  106.  
  107. header('Content-type:text/plain');
  108.  
  109. // Should print 100
  110. print calc("10*10")."\n";
  111.  
  112. // Should print 19
  113. print calc("20+-1")."\n";
  114.  
  115. // Should print 3
  116. print calc("3*3/3")."\n";
  117.  
  118. // Should print -1180
  119. print calc("-100*23/2+-30")."\n";
  120.  
  121. // Should print 8
  122. print calc("2+3*2")."\n";
  123.  
  124. // Should print 6
  125. print calc("2+2+2")."\n";
  126.  
  127. /** Bonus points :) **/
  128.  
  129. // Should print 25
  130. print calc("5*(2+3)")."\n";
  131.  
  132. // Should print 2
  133. print calc("((10/5)+(4/2))/(1+1+1-1)")."\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement