Я вважаю, що це єдине досі подання, яке не використовує ні перестановку, вбудовану, ні випадкове переміщення / сортування. Незважаючи на те, що він довший, я думаю, що алгоритм досить акуратний.
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
коли-небудь відповідь?