Есть число, например 111
, так же есть ещё 2 числа 3 и 5
на которые число 111
должно разделиться без всяких остатков и прочего...
может быть не совсем правильно словами объясняю, вот пример как это должно выглядеть:
21*5+2*3 = 111
Я не могу сформулировать нормально для своего понимания как это должно выглядеть словами, не то чтобы написать конкретный алгоритм =) собственно кто может объяснить сам принцип? хотя бы математически как то это расписать....
Решение в целых числах диофантовых уравнений вида a⋅x + b⋅y = c
можно свести к поиску коэффициентов Безу.
Если x
, y
решения уравнения a⋅x + b⋅y = d
, где d = gcd(a, b)
, тогда решением исходного уравнения будет пара: с₁⋅x
, с₁⋅y
, где с₁ = c / d
. Отсюда:
c
не делится на gcd(a, b)
, то целых решений нетимея начальное решение (x₀, y₀)
, можно найти бесконечное количество решений по формуле: (x₀ + k⋅u, y₀ - k⋅v)
, где k
произвольное целое, а u
, v
:
u = b / gcd(a, b)
v = a / gcd(a, b)
gcd(a, b)
это наибольший общий делитель. Если решение есть, то существуют такое решение x
, y
, что abs(x) < abs(u)
и abs(y) < abs(v)
.
Используя код для нахождения коэффициентов Безу из вики:
/// find integer x,y such that a*x + b*y = gcd(a, b)
function find_bezout_coeff(a, b) {
var p = 1,
q = 0,
r = 0,
s = 1,
x, y;
while (a != 0 && b != 0) {
if (a >= b) {
a = a - b;
p = p - r;
q = q - s;
} else {
b = b - a;
r = r - p;
s = s - q;
}
}
if (a != 0) {
x = p;
y = q;
} else {
x = r;
y = s;
}
return [x, y];
}
/// find integer x,y such that a*x + b*y = c
function solve_diophantine(a, b, c) {
var [x, y] = find_bezout_coeff(a, b),
d = a * x + b * y; // gcd(a, b);
if (c % d != 0)
return "no solution";
// solution: (c*x+k*b)/d, (c*y-k*a)/d for any k in Z
var c1 = c / d;
return [c1 * x, c1 * y, d];
}
(function() {
var a = 3,
b = 5,
c = 111;
var [x, y, d] = solve_diophantine(a, b, c);
console.log(`result: a*x+b*y=c: (${a}*${x} + ${b}*${y}) == ${a*x+b*y}`);
console.assert((a * x + b * y) == c);
for (var k = -3; k < 4; ++k) {
var xx = x + k * b / d,
yy = y - k * a / d;
console.log(`result: a*x+b*y=c: (${a}*${xx} + ${b}*${yy}) == ${a*xx+b*yy}`);
console.assert((a * xx + b * yy) == c);
}
})();
То, что вы хотите решить, называется линейным диофантовым уравнением и:
Алгоритмически, пожалуй, проще всего действовать подбором, хотя с точки зрения эффективности это, пожалуй, не лучший способ:
ax + by = с
Выбрать большее (чтоб считать меньше :)), скажем, это a
, и для x
от 0 до c / a
(деление целочисленное) вычислять c - ax
и смотреть, делится ли оно на b
.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Доброго времени суток всем) стоит задача переписать существующий модуль к ios устройствам для react native, а если точнее добавить таймаут при передачи...
Составил регулярное выражение,но не соображу, как добавить символ плюса вначале
Часто встречаю на GitHub модули, в описании которых присутствуют примерно такие строки: old school Grab file from dist directory