Я вважаю, що це єдине досі подання, яке не використовує ні перестановку, вбудовану, ні випадкове переміщення / сортування. Незважаючи на те, що він довший, я думаю, що алгоритм досить акуратний.
lambda L:[p for s in L for i,c in enumerate(s)for p in[c+s[:i]+s[i+1:]]if~-(p in L)][0]
Спробуйте в Інтернеті!
Пояснення
Ми робимо в основному це:
def unique_anagram(string_list):
for string in string_list:
for i, char in enumerate(string):
# Move the character to the beginning of the string
permutation = char + string[:i] + string[i+1:]
if permutation not in string_list:
return permutation
Ось доказ того, що це працює:
Для рядка Sвизначте front(S)набір рядків, отриманих шляхом вибору одного символу Sта переміщення його на передню частину S. Наприклад, front(ABCDE)є {ABCDE, BACDE, CABDE, DABCE, EABCD}.
Тепер розглянемо список анаграм L, що Lне містить усіх можливих анаграм (відповідно до опису проблеми). Ми хочемо показати, що існує рядок Sу Lтакому, який front(S)містить принаймні одну анаграму S', якої немає L.
Припустимо, від супротивного, що для кожного рядка Sв L, кожен рядок в front(S)також в L. Зауважте, що ми можемо генерувати довільну перестановку будь-якого рядка за допомогою серії "фронтальних" рухів. Наприклад, дістати
ABCDE -> BAEDC
ми можемо зробити
ABCDE -> CABDE -> DCABE -> EDCAB -> AEDCB -> BAEDC
Ми припустили, що для кожного Sв L, також кожен S'ін front(S)є L. Це також означає, що кожен S''ін front(S')є L, і так далі. Тому, якщо Sє L, кожна перестановка Sтакож є в L. Тоді Lповинен бути повний набір анаграм, суперечність.
Таким чином, оскільки ми гарантували , що існує принаймні одна перестановка НЕ в L, повинна існувати рядок Sв Lпротягом яких деякі S'в front(S)це не L. QED.
Код повторюється front(S)для кожного Sв Lі вибирає номер, S'який не знаходиться в L. За вищенаведеним результатом буде щонайменше один, S'який кваліфікується.
itertoolsколи-небудь відповідь?