Не выполняется цикл while в JavaScript
Я хотел написать код, который бы подбирал случайные целочисленные значения переменных a, b, c (от -100 до 100) в квадратном уравнении вида ax^2 + bx + c = 0. Я определил для себя условия, которым должны соответствовать эти переменные. Я использую цикл while, то бишь "пока значения переменных не будут подходить под мои условия нужно генерировать новые случайные значения". Но вместо ожидаемого результата я получаю изначальные значения переменных. Прошу помощи.?
var a = 1, b = 2, c = 3, d = 4, x1 = 5, x2 = 6;
while (d <= 0 && d !== b * b - 4 * a * c && x1 !== (-b - Math.sqrt(d)) / (2 * a) && x2 !== (-b + Math.sqrt(d)) / (2 * a)) {
var x1 = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var x2 = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var b = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var d = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var a = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var c = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
}
console.log(a, b, c, d, x1, x2);
UPD: Я переделал код по совету из комментариев: теперь переменные подбираются по самому квадратному уравнению. Я бы хотел оставить переменную x2, чтобы уравнение имело 2 корня. Но в консоли я наблюдаю только undefined :( Что мне нужно исправить?
while (a * x1 ** 2 + b * x1 + c !== 0 && a * x2 ** 2 + b * x2 + c !== 0 && a == 0 && b == 0 && c == 0 && x1 == 0 && x2 == 0) {
var a = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var b = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var c = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var x1 = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
var x2 = Math.floor(Math.random() * (100 + 100 + 1)) - 100;
}
console.log(a, b, c, x1, x2);
UPD2: Переделал наоборот. Генерируются числа, которые не подходят под решение квадратного уравнения (( Что опять не так?? ?
var a = null, b = null, c = null, x1 = null, x2 = null;
while (a * x1 ** 2 + b * x1 + c == 0 && a * x2 ** 2 + b * x2 + c == 0) {
var a = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var b = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var c = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var x1 = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var x2 = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
}
console.log(a, b, c, x1, x2);
Ответы (2 шт):
Предлагаю использовать немного другой подход. Ваша задача - получить уравнение с целыми коэффициентами. При это корни могут быть рациональными (дроби). Пусть первый корень x1=p/q, второй x2=r/s, где p,q,r,s - целые числа, не равные нулю (числители могут быть нулевые, но тогда корень будет нулевой - не знаю, желательно ли это в вашем случае)
Тогда квадратное уравнение
(x-p/q)*(x-r/s) = 0 преобразовав, получаем
q*s*x^2 + (-p*s-r*q)*x + p*r = 0
или
a = q*s
b = (-p*s-r*q)
c = p*r
Таким образом, генерируем четыре целых числа, делаем из них коэффициенты. Могу показать код на Python, думаю, суть будет понятна. Для того, чтобы не было коэффициентов с общим множителем (типа 3,-6, 12), можно сократить на НОД (gcd) всех трёх коэффициентов
import random, math
p = random.randint(-10,10)
r = random.randint(-10,10)
q = 0
while q == 0:
q = random.randint(-10,10)
s = 0
while s == 0:
s = random.randint(-10,10)
a = q*s
b = - (p*s + r*q)
c = p*r
gab = math.gcd(a,b)
gbc = math.gcd(c,b)
gabc = math.gcd(gab, gbc)
a //= gabc
b //= gabc
c //= gabc
print(a, b, c, p/q, r/s)
Примеры вывода:
7 31 30 -3.0 -1.4285714285714286
32 28 5 -0.625 -0.25
-8 13 -5 1.0 0.625
Вот код:
while (a * x1 ** 2 + b * x1 + c == 0 && a * x2 ** 2 + b * x2 + c == 0) {
...
}
Тут написано: пока x1 корень уравнения и x2 корень уравнения продолжай работу.
Это значит что у вас условие написано наоборот. Продолжать работу надо пока x1 не корень уравнения или x2 не корень уравнения:
while (a * x1 ** 2 + b * x1 + c != 0 || a * x2 ** 2 + b * x2 + c != 0) {
...
}
К сожалению, вы немедленно получите пять null на печати. Это ещё одна проблема: условие проверяется до того как переменные получат числовые значения. JavaScript в этом случае работает необычно, не буду на этом останавливаться. Просто присвою a, b, c, x1, x2 числовые значения. Но такие чтобы равенства не получилось, иначе мы всегда будем получать одно решение.
Если теперь запустить код, он начнёт работать и никогда не остановится. Потому что мы подбираем положительные корни в уравнение с положительными коэффициэнтами. Равенства так не получить никогда. Надо что величины хотя бы иногда могли быть отрицательными:
var a = 1, b = 2, c = 3, x1 = 4, x2 = 5;
while (a * x1 ** 2 + b * x1 + c != 0 || a * x2 ** 2 + b * x2 + c != 0) {
a = Math.floor(Math.random() * 21) - 10;
b = Math.floor(Math.random() * 21) - 10;
c = Math.floor(Math.random() * 21) - 10;
x1 = Math.floor(Math.random() * 21) - 10;
x2 = Math.floor(Math.random() * 21) - 10;
}
console.log(a, b, c, x1, x2);
$ node equation.js -6 -9 0 0 0 $ node equation.js 1 0 -9 -3 -3 $ node equation.js 1 1 -6 -3 2
Тут видно что мы часто получаем решения где x1 == x2. Это условие надо добавить в заголовок цикла, надеюсь это вы сможете сделать сами.