Дан набор формул, подобных этому:
bacb
bcab
cbba
abbc
Дайте алгоритм, который находит количество уникальных результатов, которые вы можете получить, когда каждая переменная заменяется на «0» или «1» в каждой формуле.
Есть (k!)^2
формулы, каждая с 2k-1
переменными и k^2
терминами. Выразите свою асимптотику в терминах k
.
Самый быстрый алгоритм выигрывает. В случае ничьей выигрывает решение с меньшим использованием асимптотической памяти. Если это все еще ничья, первый пост выигрывает.
Для приведенного выше примера можно получить следующие результаты, подставив переменные:
1110, 0110, 1001, 0100, 1000, 0000, 0010, 1101, 1111, 0001, 1011, 0111
Таким образом, правильный ответ - 12. Среди прочего, 1010
нельзя сделать, используя приведенные выше формулы.
Я сделал еще три теста с соответствующими решениями 230 , 12076 и 1446672 .
a
,b
... является переменной ? А у нас всегда только неравномерное количество переменных? Не имеет значения, какова длина последовательности переменных и сколько формул вам дано?Ответы:
Mathematica, O (k ^ 2 (k!) ^ 2) время
Надеюсь, я правильно рассчитал сложность времени. Ввод представляет собой список формул, таких как
{"bacb","bcab","cbba","abbc"}
. Запускается менее чем за 30 секунд для каждого теста на моей машине, но кого волнует абсолютное время?Объяснение:
&
в конце делает его чистой функцией,#
ссылаясь на первый аргумент,#2
являясь вторым аргументом и т. Д.Length[*..*]
берет длину списка, содержащегося в нем.Union@@(*..*)
берет содержащийся список и предоставляет его в качестве аргументов дляUnion
, который возвращает список уникальных элементов в любом из своих аргументов.*..*&/@#
берет чистую функцию и отображает ее в списке формул, так что{a,b,c}
становится{f[a],f[b],f[c]}
. Обратите внимание, что во вложенных чистых функциях#n
ссылается на свои внутренние аргументы.Fold[*..*&,#,*..*]
принимает функцию аккумулятора, начальное значение, список и возвращаетf[f[...[f[starting value,l_1],l_2],...],l_n]
.Union[Characters[#]]
берет все символы в текущей формуле и получает все уникальные элементы, давая нам переменные.Flatten[*..*]
сглаживает свой аргумент, так что{{{a},b},{{c,{d}}}}
становится{a,b,c,d}
.{*..*,*..*}
это просто способ объединить два результата, используя вышеFlatten
.StringReplace[#,#2->"0/1"]
принимает предыдущий результат и возвращает его с заменой текущей переменной либо на,0
либо на1
.источник
k
в качестве переменной в свое время? Все-таки факториальное время! Уф!k
». Кроме того, я должен был сделатьGeneralUtilities`Benchmark
для каждого используемого метода.