Проблема
Скажем, у вас есть два списка A = [a_1, a_2, ..., a_n]
и B = [b_1, b_2, ..., b_n]
целых чисел. Скажем, A
потенциально-делимый на B
, если существует перестановка B
, которая делает a_i
делимой на b_i
для всех i
. Тогда возникает проблема: можно ли переупорядочить (т.е. Переставить) B
, чтобы a_i
делится на b_i
для всех i
?
Например, если у вас есть
A = [6, 12, 8]
B = [3, 4, 6]
Тогда ответ будет True
, так как B
можно переупорядочить как B = [3, 6, 4]
, а затем мы будем иметь a_1 / b_1 = 2
, a_2 / b_2 = 2
и a_3 / b_3 = 2
, все из которых являются целыми числами, поэтому A
является потенциально делящимся на B
.
В качестве примера, который должен выводить False
, мы могли бы иметь:
A = [10, 12, 6, 5, 21, 25]
B = [2, 7, 5, 3, 12, 3]
Причина, по которой это False
, заключается в том, что мы не можем изменить порядок B
, так как 25 и 5 находятся в A
, но единственным делителем в B
будет 5, поэтому можно было бы оставить без изменений.
Подход
Очевидно, что простой подход состоял бы в том, чтобы получить все перестановки B
и посмотреть, будет ли удовлетворять делимости потенциала, что-то вроде строк:
import itertools
def is_potentially_divisible(A, B):
perms = itertools.permutations(B)
divisible = lambda ls: all( x % y == 0 for x, y in zip(A, ls))
return any(divisible(perm) for perm in perms)
Вопрос
Каков самый быстрый способ узнать, является ли список потенциально делящимся другим списком? Есть предположения? Я думал, если есть умный способ сделать это с помощью простых чисел, но я не смог найти решение.
Очень ценно!
Изменить: Это, вероятно, не имеет отношения к большинству из вас, но, ради полноты, я объясню свою мотивацию. В теории групп существует гипотеза о конечных простых группах о том, существует ли биекция из неприводимых характеров и классов сопряженности группы такая, что каждая степень характера делит соответствующий размер класса. Например, для U6 (4) вот как выглядят A
и B
. Довольно большие списки, заметьте!