Кількість унікальних результатів шляхом заміни змінних


9

Дано набір таких формул:

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 .


Пояснення: що є k у питанні? Це просто якась абстрактна константа?
isaacg

@isaacg Так. Це, наприклад, запобігання зв’язків між рішеннями, які швидші за меншими, але більшими формулами.
orlp

Так кожен лист a, b... є змінною ? І у нас завжди лише нерівномірна кількість змінних? Чи не має значення тривалість послідовності змінних і скільки формул вам надано?
flawr

@flawr Точне співвідношення між кількістю змінних, кількістю термінів та кількістю формул наведено у питанні.
orlp

Чи "може бути" означає, що ви можете отримати до $ (k!) ^ 2 $ формул, чи є саме формули $ (k!) ^ 2 $? Крім того, чи є у вас додатки для алгоритму з цими специфікаціями? Я просто запитую, бо характеристики здаються досить умовними.
flawr

Відповіді:


2

Mathematica, O (k ^ 2 (k!) ^ 2) час

Length[Union@@(Fold[Flatten[{StringReplace[#,#2->"0"],StringReplace[#,#2->"1"]}]&,#,Union[Characters[#]]]&/@#)]&

Сподіваюся, я правильно розрахував складність часу. Введення - це список таких формул, як {"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як змінну свого часу? Все-таки факторський час! Фу!
theonlygusti

Оп сказав: "Висловіть свою асимптотику з точки зору k". Крім того, я повинен був зробити GeneralUtilities`Benchmarkдля кожного використовуваного методу.
LegionMammal978

Хочете додати звичайний англійський опис свого алгоритму? Я незнайомий з Mathematica, тому не можу перевірити ваше рішення.
orlp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.