Код-гольфіст спосіб пошуку бібліотеки


15

Виклик:

У моїй музичній колекції тисячі пісень, і на щастя для мене, мій улюблений плеєр має функцію пошуку. У мене також чудова пам’ять - я пам'ятаю назву кожної пісні в своїй колекції. Однак я дуже ледачий і не люблю набирати текст - кожен додатковий набір клавіш - справа!

  • Яку найкоротшу струну потрібно шукати, щоб виділити одну пісню? Допоможіть мені запам'ятати список клавіш, якими я можу скористатися, щоб мінімізувати введення тексту під час пошуку!

Це , тому найкоротший код виграє.


Правила:

З огляду на вхідний список назв пісень, сформуйте перелік ключових запитів із урахуванням таких обмежень:

  1. Кожна назва пісні повинна мати ключ пошуку.
  2. Загальна кількість символів у списку вихідних даних повинна бути якомога меншою.
  3. Мій улюблений музичний плеєр - foobar2000 :
    • Функція пошуку не відрізняється від регістру. ( appleте саме, що aPpLE).
    • Кожен ключ пошуку повинен складатися з одного або декількох "слів" у будь-якому порядку, розділених пробілами:
      • Кожне слово має бути підрядком відповідної назви пісні.
      • Якщо одна і та ж підрядка задана кілька разів, то вона повинна виникати стільки разів у відповідному заголовку пісні.
      • Якщо сама підрядка містить пробіл, то ця підрядка повинна бути оточена лапками.

Підказки:

  • Часто для деяких назв пісень існує правило, що відповідає правилам 2. Кілька пошукових ключів. У такому випадку будь-яка одна клавіша зробить, але ви отримаєте очки браузера, щоб перерахувати їх усі.
  • Ви можете припустити, що в списку введення будуть лише символи ASCII, але бали брауні будуть присвоєні за сумісність UTF-8.
  • Чи було важко дотримуватись Правила 3? Ось як це працює:


Приклад:

Якщо моя музична колекція складалася лише з двох альбомів, Майкл Джексон " Зі стіни" та " Трилер" :

Ви можете скористатися списками вище для тестування програми. Ось попередня версія другого списку:

["Don't Stop 'Til You Get Enough","Rock with You","Working Day and Night","Get on the Floor","Off the Wall","Girlfriend","She's out of My Life","I Can't Help It","It's the Falling in Love","Burn This Disco Out","Wanna Be Startin' Somethin'","Baby Be Mine","The Girl Is Mine","Thriller","Beat It","Billie Jean","Human Nature","P.Y.T. (Pretty Young Thing)"]

1
Чи є у вас приклад, який вимагає декількох рядків для ключа?
Джонатан Аллан

1
Як щодо ["Wanta Be A Wanna B","Wanta Bea A Wanna B","Wanna Be A Wanna Bea"]?
Джонатан Аллан

... але що вони / можуть бути, якщо в самих підрядках не допускається пробілів - зауважте, що всі цілі слова стикаються.
Джонатан Аллан

Чому сира версія у спойлері?
Leaky Nun

Відповіді:


4

Python 2, 556 байт

Спробуйте в Інтернеті.

-10 байт, завдяки @Riker, @ovs

Взяв у мене пару вечорів, щоб все спрацювало.
Виводить назву пісні, масив клавіш пошуку та довжину пошукових клавіш у поєднанні (включаючи пробіли та лапки)

import re
S=map(str.lower,input())
T=len
for s in S:
 y=s;n=T(s)
 def R(r,t):
    global n,y
    l=T(' '.join(t))+2*sum(map(lambda x:' 'in x,t))
    if l>n:return
    if(lambda K:T([s for s in S if T(s)-T(reduce(lambda x,y:re.sub(re.escape(y),'',x,1),K,s))==T(''.join(K))])==1)(t)and l<n:y=t;n=l
    u=[(lambda s,n:n and[''.join(y) for y in eval('zip(s%s)'%(''.join(',s[%s:]'%-~x for x in range(n))))]or list(s))(r,i)for i in range(T(r))]
    for i in range(T(r)):
     for j in range(T(r)-i):R(r[j+T(u[i][j]):],t+[u[i][j]])
 R(s,[])
 print[' 'in x and'"%s"'%x or x for x in y]

Деякі пояснення:

T=len

Тут len()використовується дуже часто функція , тому це перейменування економить байти


L=lambda s,n:n and[''.join(y) for y in eval('zip(s%s)'%(''.join(',s[%s:]'%-~x for x in range(n))))]or list(s)

Оцінює всі можливі підрядки рядка s довжина n.
eval(...)створює команду zip(s,s[1:],s[2:],...,s[n:])
Створює підрядки довжини nз кожного індексу, sякщо це можливо. Так що, s='budd'і n='2'це буде виробляти bu, ud, dd


F=lambda K:len([s for s in S if len(s)-len(reduce(lambda x,y:re.sub(re.escape(y),'',x,1),K,s))==len(''.join(K))])==1

Фільтр, щоб перевірити, чи передбачені клавіші (K) для унікальної назви пісні.
re.sub потрібен для декількох однакових ключів, наприклад ['nn', 'nn'] у прикладах.


Внутрішня функція def R(r,t)є рекурсивною для створення всіх можливих комбінацій підрядків, які можуть описувати назву пісні.
Кожна комбінація порівнюється з найкоротшою на даний момент (якщо вона була), щоб зменшити кількість створених комбінацій - якщо вона більша, вона не буде прийнята як усі її похідні.
Функція використовує 2 змінних для відстеження стану: nдля довжини поточної найкоротшої комбінації клавіш та yдля самої комбінації


l=T(' '.join(t))+2*sum(map(lambda x:' 'in x,t))

Це обчислює довжину комбінації клавіш. ' '.joinдодайте пробіли між клавішами і 2*sum(...)обчислює кількість необхідних лапок для ключів з пробілами.


u=[L(r,i)for i in range(0,T(r))]

Використовує першу лямбда-функцію, щоб отримати всі можливі комбінації клавіш (будь-якої можливої ​​довжини) для поточного рядка.


Два для циклів, щоб переглянути всі згенеровані ключі та передати їх окремо до наступного рекурсивного кроку. Ключове місце ( j) необхідно , щоб правильно скибочку рядок в кінці цього: r[j+T(u[i][j]):].
У фрагменті передбачено рядок, який розпочався там, де закінчується поточний ключ, тому не буде перекриттів.
Якщо місце невідоме, рівні клавіші зіпсують все.


[' 'in x and'"%s"'%x or x for x in y]

Набагато довше, ніж просто y, але клавіші з пробілами повинні бути оточені лапками


Це дивно. Ти перший, хто отримав правило 3 правильно!
аяне

1
До речі, ви повинні мати можливість голити два байти, видаливши 0,в одному зі своїх діапазонів: u=[L(r,i)for i in range(0,T(r))]=> u=[L(r,i)for i in range(T(r))].
notjagan

1
Ви можете зберегти ще кілька байтів: у вашому висновку не потрібно показувати вхідні рядки та розмір вихідних рядків.
аяне

@ 彩 音 М Дякую! Я обрізав ці кілька байт із діапазону та виводу.
Мертвий Поссум

1
S=map(str.lower,input())за -5 байт
ов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.