Приветствую всех! Пишу ребёнку тест по математике (чтобы решала примеры, а скрипт проверял их правильность). Примеры генерируются рекурсивной функцией, которая сама себя запускает ещё раз, если результат примера получается отрицательный (рано дочке ещё отрицательные числа учить, первый класс всё-таки). Вот код: Код (Text): <?php function generateHigh($min, $max) { $a = mt_rand($min, $max); $b = mt_rand($min, $max); $c = mt_rand($min, $max); $d = mt_rand($min, $max); $operator1 = mt_rand(1, 2); $operator2 = mt_rand(1, 2); $operator3 = mt_rand(1, 2); switch ( $operator1 ) { case 1 : { $result = $a + $b; $showOp1 = " + "; } break; case 2 : { $result = $a - $b; $showOp1 = " - "; } break; } if ( $result < 0 ) { generateHigh($id, $min, $max); } switch ( $operator2 ) { case 1 : $result = $result + $c; $showOp2 = " + "; break; case 2 : $result = $result - $c; $showOp2 = " - "; break; } if ( $result < 0 ) { generateHigh($id, $min, $max); } switch ( $operator3 ) { case 1 : $result = $result + $d; $showOp3 = " + "; break; case 2 : $result = $result - $d; $showOp3 = " - "; break; } if ( $result < 0 ) { generateMed($id, $min, $max); } $_SESSION['QUIZ'] = $a.$showOp1.$b.$showOp2.$c.$showOp3.$d; // строка, которую нарисуем $_SESSION['RESULT'] = $result; // результат } ?> В нём случайно генерятся 4 слагаемых и случайно генерятся операторы - "+" или "-". Результатом работы функции должен быть пример вида: 3 + 12 - 14 + 19. Причём: 1) общий результат должен быть неотрицательный. 2) результат операции с каждой парой чисел тоже должен быть неотрицательный. Вроде всё правильно написал, но функция всё равно генерит иногда примеры вида 1 - 18 + 2 + 1. То есть, ребёнок явно не сможет от 1 отнять 18... Это всё меня очень печалит... Мне пора в первый класс по программированию, да? Взываю к коллективному разуму! Всем заранее спасибо.
попробуйте такую, без рекурсии Код (PHP): function genExample($min, $max) { $s = ''; $last = 0; $ops = array_slice(str_split(str_shuffle('+-+-')),0,3); foreach($ops as $k=>$op) { if ($op=='-') { if ($k==0) { $b = mt_rand($min,$max); $a = mt_rand($b,$max+$b); $last = $a-$b; $s = $a.$op.$b; } else { $c = mt_rand($min,$last); $last -= $c; $s .= $op.$c; } } elseif ($op=='+') { if ($k==0) { list($a,$b)=array(mt_rand($min,$max), mt_rand($min,$max)); $last = $a+$b; $s = $a.$op.$b; } else { $c = mt_rand($min,$max); $last += $c; $s .= $op.$c; } } } return $s; } // $s = genExample(1,10); // 11-5+3-3 echo $s;
runcore, спасибо, попробовал. Работает хорошо, но в 1-м случае из 10 проскакивает подобное: 7+3-10-2. Отрицательный результат. Поэтому, still trying...
а ну да. там получается 0 в одной из операций, и для того чтоб небыло отрицального результата при вычитании нужно брать вторым числом тоже ноль, а при вызове функции мы задали диапазон от 1 до 10. тоесть ноль никак не взять. вот подправил Код (PHP): function genExample($min, $max) { $s = ''; $last = 0; $ops = array_slice(str_split(str_shuffle('+-+-')),0,3); foreach($ops as $k=>$op) { if ($op=='-') { if ($k==0) { $b = mt_rand($min,$max-1); $a = mt_rand($b,$max); $last = $a-$b; $s = $a.$op.$b; } else { $c = mt_rand(min($min,$last),$last); $last -= $c; $s .= $op.$c; } } elseif ($op=='+') { if ($k==0) { list($a,$b)=array(mt_rand($min,$max), mt_rand($min,$max)); $last = $a+$b; $s = $a.$op.$b; } else { $c = mt_rand($min,$max); $last += $c; $s .= $op.$c; } } } return $s; }
Я не вкурсе, но при вызове функции внутри её ты передаёшь три параметра: $id,$min,$max, тогда как сама функция описана только с двумя.
$id - это всего лишь номер вопроса. У меня их 20. Передаю id, генерю вопрос, ответ, и по номеру вопроса возвращаю из функции вопрос и ответ через сессию. Согласен, топорно, да. Но по-другому пока не придумал. Просто, когда задавал вопрос тут, $id я опустил. Это - сложность вопроса. У меня 3 функции: generateLow (генерирует 2 слагаемых, типа 2+2), generateMed(три слагаемых, типа 6+11-14) и generateHigh(самая сложная, 4 слагаемых, типа 11+16-9+4)
В-общем, джентльмены, переписал я свою функцию. Вот что значит - работать на свежую голову! Ночью сидел, ничего не соображал. Сейчас отдохнувший и выспавшийся - написал за 10 минут Вот что получилось в итоге: Код (Text): <?php function genMed($id, $min, $max) { // Функция генерирует пример из трёх слагаемых по следующим условиям: // 1. Общий результат должен быть неотрицательным // 2. Результат операции над каждой из двух пар тоже должен быть неотрицательным $result = 0; $a = mt_rand($min, $max); $b = mt_rand($min, $max); $operator1 = mt_rand(1, 2); // 1 - "-", 2 - "+" if ( $operator1 == 1 && ($b >= $a) ) { genMed($id, $min, $max); } else { switch ( $operator1 ) { case 1: $result = $a - $b; $showOp1 = " - "; break; case 2: $result = $a + $b; $showOp1 = " + "; break; } $c = mt_rand($min, $max); $operator2 = mt_rand(1, 2); // 1 - "-", 2 - "+" if ( $operator2 == 1 && ($c >= $result) ) { genMed($id, $min, $max); } else { switch ( $operator2 ) { case 1: $result = $result - $b; $showOp2 = " - "; break; case 2: $result = $result + $b; $showOp2 = " + "; break; } $_SESSION[$id.'_QUIZ'] = $a.$showOp1.$b.$showOp2.$c; $_SESSION[$id.'_RESULT'] = $result; } } unset($a, $b, $c, $result, $showOp1, $showOp2, $operator1, $operator2); } ?> Всем - большое спасибо за помощь и советы!