Ejemplo n.º 1
0
 /**
  * Returns the best solution for a given pass of a participant
  * @return array An associated array containing the best solution
  * @access public
  */
 public function getBestSolution($solutions)
 {
     $user_solution = array();
     foreach ($solutions as $idx => $solution_value) {
         if (preg_match("/^(\\\$v\\d+)\$/", $solution_value["value1"], $matches)) {
             $user_solution[$matches[1]] = $solution_value["value2"];
             $varObj = $this->getVariable($matches[1]);
             $varObj->setValue($solution_value["value2"]);
         } else {
             if (preg_match("/^(\\\$r\\d+)\$/", $solution_value["value1"], $matches)) {
                 if (!array_key_exists($matches[1], $user_solution)) {
                     $user_solution[$matches[1]] = array();
                 }
                 $user_solution[$matches[1]]["value"] = $solution_value["value2"];
             } else {
                 if (preg_match("/^(\\\$r\\d+)_unit\$/", $solution_value["value1"], $matches)) {
                     if (!array_key_exists($matches[1], $user_solution)) {
                         $user_solution[$matches[1]] = array();
                     }
                     $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
                 }
             }
         }
     }
     foreach ($this->getResults() as $result) {
         $resVal = $result->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), false);
         if (is_object($result->getUnit())) {
             $user_solution[$result->getResult()]["unit"] = $result->getUnit()->getId();
             $user_solution[$result->getResult()]["value"] = $resVal;
         } else {
             if ($result->getUnit() == NULL) {
                 $unit_factor = 1;
                 // there is no fix result_unit, any "available unit" is accepted
                 $available_units = $result->getAvailableResultUnits(parent::getId());
                 $result_name = $result->getResult();
                 if ($available_units[$result_name] != NULL) {
                     $check_unit = in_array($user_solution[$result_name]['unit'], $available_units[$result_name]);
                 }
                 if ($check_unit == true) {
                     //get unit-factor
                     $unit_factor = assFormulaQuestionUnit::lookupUnitFactor($user_solution[$result_name]['unit']);
                     $user_solution[$result->getResult()]["value"] = round(ilMath::_div($resVal, $unit_factor), 55);
                 }
             }
         }
         if ($result->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC || $result->getResultType() == assFormulaQuestionResult::RESULT_FRAC) {
             $value = assFormulaQuestionResult::convertDecimalToCoprimeFraction($resVal);
             if (is_array($value)) {
                 $frac_helper = $value[1];
                 $value = $value[0];
             }
             $user_solution[$result->getResult()]["value"] = $value;
             $user_solution[$result->getResult()]["frac_helper"] = $frac_helper;
         } elseif ($result->getPrecision() > 0) {
             $user_solution[$result->getResult()]["value"] = round($resVal, $result->getPrecision());
         } else {
             $user_solution[$result->getResult()]["value"] = round($resVal);
         }
     }
     return $user_solution;
 }
Ejemplo n.º 2
0
 public static function _sub($left_operand, $right_operand, $scale = 50)
 {
     if (function_exists("bcsub")) {
         return bcsub(ilMath::exp2dec($left_operand), ilMath::exp2dec($right_operand), $scale);
     } else {
         $res = $left_operand - $right_operand;
         if (is_numeric($scale)) {
             $res = round($res, $scale);
         }
         return $res;
     }
 }
Ejemplo n.º 3
0
 /**
  * @param $fNumber
  * @return string
  * function fixes problem which occur when locale ist set to de_DE for example,
  * because bc* function expecting strings
  */
 private static function bcconv($fNumber)
 {
     $fNumber = ilMath::exp2dec($fNumber);
     $locale_info = localeconv();
     if ($locale_info["decimal_point"] != ".") {
         $sAppend = '';
         $iDecimals = ini_get('precision') - floor(log10(abs($fNumber)));
         if (0 > $iDecimals) {
             $fNumber *= pow(10, $iDecimals);
             $sAppend = str_repeat('0', -$iDecimals);
             $iDecimals = 0;
         }
         return number_format($fNumber, $iDecimals, '.', '') . $sAppend;
     }
     return $fNumber;
 }
 function getBaseValue()
 {
     if (!is_object($this->getUnit())) {
         return $this->value;
     } else {
         include_once "./Services/Math/classes/class.ilMath.php";
         return ilMath::_mul($this->value, $this->getUnit()->getFactor());
     }
 }
 public function getRangeMaxBase()
 {
     if (is_numeric($this->getRangeMax())) {
         if (is_object($this->getUnit())) {
             include_once "./Services/Math/classes/class.ilMath.php";
             return ilMath::_mul($this->getRangeMax(), $this->getUnit()->getFactor(), 100);
         }
     }
     return $this->getRangeMax();
 }
Ejemplo n.º 6
0
 function pfx($tokens, $vars = array())
 {
     if ($tokens == false) {
         return false;
     }
     $stack = new EvalMathStack();
     foreach ($tokens as $token) {
         // nice and easy
         // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
         if (in_array($token, array('+', '-', '*', '/', '^'))) {
             if (is_null($op2 = $stack->pop())) {
                 return $this->trigger("internal error");
             }
             if (is_null($op1 = $stack->pop())) {
                 return $this->trigger("internal error");
             }
             include_once "class.ilMath.php";
             switch ($token) {
                 case '+':
                     $stack->push(ilMath::_add($op1, $op2));
                     break;
                 case '-':
                     $stack->push(ilMath::_sub($op1, $op2));
                     break;
                 case '*':
                     $stack->push(ilMath::_mul($op1, $op2));
                     break;
                 case '/':
                     if ($op2 == 0) {
                         return $this->trigger("division by zero");
                     }
                     $stack->push(ilMath::_div($op1, $op2));
                     break;
                 case '^':
                     $stack->push(ilMath::_pow($op1, $op2));
                     break;
             }
             // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
         } elseif ($token == "_") {
             $stack->push(-1 * $stack->pop());
             // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
         } elseif (preg_match("/^([a-z]\\w*)\\(\$/", $token, $matches)) {
             // it's a function!
             $fnn = $matches[1];
             if (in_array($fnn, $this->fb)) {
                 // built-in function:
                 if (is_null($op1 = $stack->pop())) {
                     return $this->trigger("internal error");
                 }
                 $fnn = preg_replace("/^arc/", "a", $fnn);
                 // for the 'arc' trig synonyms
                 if ($fnn == 'ln') {
                     $fnn = 'log';
                 }
                 eval('$stack->push(' . $fnn . '($op1));');
                 // perfectly safe eval()
             } elseif (array_key_exists($fnn, $this->f)) {
                 // user function
                 // get args
                 $args = array();
                 for ($i = count($this->f[$fnn]['args']) - 1; $i >= 0; $i--) {
                     if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop())) {
                         return $this->trigger("internal error");
                     }
                 }
                 $stack->push($this->pfx($this->f[$fnn]['func'], $args));
                 // yay... recursion!!!!
             }
             // if the token is a number or variable, push it on the stack
         } else {
             if (is_numeric($token)) {
                 $stack->push($token);
             } elseif (($hex = $this->from_hexbin($token)) !== FALSE) {
                 $stack->push($hex);
             } elseif (array_key_exists($token, $this->v)) {
                 $stack->push($this->v[$token]);
             } elseif (array_key_exists($token, $vars)) {
                 $stack->push($vars[$token]);
             } else {
                 return $this->trigger("undefined variable '{$token}'");
             }
         }
     }
     // when we're out of tokens, the stack should have a single element, the final result
     if ($stack->count != 1) {
         return $this->trigger("internal error");
     }
     return $stack->pop();
 }