W mojej kolekcji muzycznej mam tysiące piosenek i na szczęście mój ulubiony odtwarzacz ma funkcję wyszukiwania. Mam też świetną pamięć - pamiętam tytuł każdej piosenki w mojej kolekcji. Jestem jednak bardzo leniwy i nie lubię pisać na klawiaturze - każde dodatkowe naciśnięcie klawisza jest obowiązkiem!
Jaki jest najkrótszy ciąg, którego muszę szukać, aby wyodrębnić jedną piosenkę? Pomóż mi zapamiętać listę klawiszy, których mogę użyć, aby zminimalizować pisanie podczas wyszukiwania!
To jest golf golfowy , więc wygrywa najkrótszy kod.
Zasady:
Biorąc pod uwagę listę tytułów utworów, wygeneruj listę kluczy wyszukiwania z zastrzeżeniem następujących ograniczeń:
Każdy tytuł utworu powinien mieć klawisz wyszukiwania.
Całkowita liczba znaków na liście wyników musi być jak najmniejsza.
Funkcja wyszukiwania nie rozróżnia wielkości liter. ( applejest taki sam jak aPpLE).
Każdy klucz wyszukiwania musi składać się z jednego lub więcej „słów”, w dowolnej kolejności, oddzielonych spacjami:
Każde słowo musi być podciągiem odpowiedniego tytułu piosenki.
Jeśli ten sam podciąg zostanie podany wiele razy, to musi wystąpić wiele razy w odpowiednim tytule utworu.
Jeśli sam podciąg zawiera spację, to ten podciąg musi być otoczony cudzysłowami.
Poradnik:
Często w przypadku niektórych tytułów utworów istnieje kilka klawiszy wyszukiwania spełniających zasadę 2. W takim przypadku wystarczy jeden klawisz, ale otrzymasz punkty brownie za ich listę.
Możesz założyć, że na liście wejściowej będą tylko znaki ASCII, ale punkty brownie zostaną przyznane za zgodność UTF-8.
Czy przestrzeganie zasady 3 było trudne? Oto jak to działa:
Możesz użyć powyższych list do przetestowania swojego programu. Oto surowa wersja drugiej listy:
["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)"]
Zajęło mi kilka wieczorów, żeby wszystko działało.
Wyświetla nazwę utworu, tablicę klawiszy wyszukiwania i długość klawiszy wyszukiwania (łącznie ze spacjami i cudzysłowami)
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]
Niektóre wyjaśnienia:
T=len
Funkcja len()używana tutaj bardzo często, więc zmiana nazwy pozwala zaoszczędzić bajty
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)
Ocenia wszystkie możliwe podciągi długości łańcucha n. eval(...)tworzy polecenie zip(s,s[1:],s[2:],...,s[n:])
Tworzy podciągi długości nz każdego indeksu, sjeśli to możliwe. Więc dla s='budd'i n='2'będzie produkować 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
Filtruj, aby sprawdzić, czy dostarczone klawisze (K) dotyczą unikalnej nazwy utworu.
re.sub jest wymagane dla wielu identycznych kluczy, takich jak ['nn', 'nn'] w przykładach.
Funkcja wewnętrzna def R(r,t)jest rekurencyjna, aby utworzyć wszystkie możliwe kombinacje podciągów, które mogą opisywać nazwę piosenki.
Każda kombinacja jest porównywana z aktualnie najkrótszą (jeśli taka była) z mniejszą liczbą utworzonych kombinacji - jeśli jest większa, nie będzie akceptowana jako wszystkie pochodne.
Funkcja używa 2 zmiennych do śledzenia stanu: ndla długości bieżącej najkrótszej kombinacji klawiszy i ydla samej kombinacji
l=T(' '.join(t))+2*sum(map(lambda x:' 'in x,t))
Oblicza to długość kombinacji klawiszy. ' '.joindodaj spacje między kluczami i 2*sum(...)oblicza liczbę potrzebnych cudzysłowów dla kluczy ze spacjami.
u=[L(r,i)for i in range(0,T(r))]
Używa pierwszej funkcji lambda, aby uzyskać wszystkie możliwe kombinacje klawiszy (każdej możliwej długości) dla bieżącego ciągu.
Dwa dla cykli, aby przejrzeć wszystkie wygenerowane klucze i przekazać je indywidualnie do następnego rekurencyjnego kroku. Kluczem miejsce ( j) jest potrzebny do prawidłowego slice ciąg na jego końcu: r[j+T(u[i][j]):].
Plaster zapewnia ciąg znaków, który zaczyna się tam, gdzie kończy się bieżący klucz, więc nie będzie nakładania się.
Jeśli miejsce jest nieznane, równe klucze zepsułyby wszystko.
[' 'in x and'"%s"'%x or x for x in y]
Znacznie dłużej niż tylko y, ale klawisze ze spacjami powinny być otoczone cudzysłowami
To jest niesamowite. Jesteś pierwszym, który uzyskał prawidłową zasadę 3!
ayane
1
Nawiasem mówiąc, powinieneś być w stanie ogolić dwa bajty, usuwając 0,jeden z twoich zakresów: u=[L(r,i)for i in range(0,T(r))]=> u=[L(r,i)for i in range(T(r))].
notjagan
1
Możesz zapisać jeszcze kilka bajtów: w danych wyjściowych nie musisz pokazywać ciągów wejściowych i wielkości ciągów wyjściowych.
ayane
@ 彩 音 M Dzięki! Skróciłem te kilka bajtów z zakresu i wyjścia.
["Wanta Be A Wanna B","Wanta Bea A Wanna B","Wanna Be A Wanna Bea"]
?Odpowiedzi:
Python 2, 556 bajtów
Wypróbuj online.
-10 bajtów, dzięki @Riker, @ovs
Zajęło mi kilka wieczorów, żeby wszystko działało.
Wyświetla nazwę utworu, tablicę klawiszy wyszukiwania i długość klawiszy wyszukiwania (łącznie ze spacjami i cudzysłowami)
Niektóre wyjaśnienia:
Funkcja
len()
używana tutaj bardzo często, więc zmiana nazwy pozwala zaoszczędzić bajtyOcenia wszystkie możliwe podciągi długości łańcucha n.
eval(...)
tworzy poleceniezip(s,s[1:],s[2:],...,s[n:])
Tworzy podciągi długości
n
z każdego indeksu,s
jeśli to możliwe. Więc dlas='budd'
in='2'
będzie produkować bu, ud, ddFiltruj, aby sprawdzić, czy dostarczone klawisze (K) dotyczą unikalnej nazwy utworu.
re.sub jest wymagane dla wielu identycznych kluczy, takich jak ['nn', 'nn'] w przykładach.
Funkcja wewnętrzna
def R(r,t)
jest rekurencyjna, aby utworzyć wszystkie możliwe kombinacje podciągów, które mogą opisywać nazwę piosenki.Każda kombinacja jest porównywana z aktualnie najkrótszą (jeśli taka była) z mniejszą liczbą utworzonych kombinacji - jeśli jest większa, nie będzie akceptowana jako wszystkie pochodne.
Funkcja używa 2 zmiennych do śledzenia stanu:
n
dla długości bieżącej najkrótszej kombinacji klawiszy iy
dla samej kombinacjiOblicza to długość kombinacji klawiszy.
' '.join
dodaj spacje między kluczami i2*sum(...)
oblicza liczbę potrzebnych cudzysłowów dla kluczy ze spacjami.Używa pierwszej funkcji lambda, aby uzyskać wszystkie możliwe kombinacje klawiszy (każdej możliwej długości) dla bieżącego ciągu.
Dwa dla cykli, aby przejrzeć wszystkie wygenerowane klucze i przekazać je indywidualnie do następnego rekurencyjnego kroku. Kluczem miejsce (
j
) jest potrzebny do prawidłowego slice ciąg na jego końcu:r[j+T(u[i][j]):]
.Plaster zapewnia ciąg znaków, który zaczyna się tam, gdzie kończy się bieżący klucz, więc nie będzie nakładania się.
Jeśli miejsce jest nieznane, równe klucze zepsułyby wszystko.
Znacznie dłużej niż tylko
y
, ale klawisze ze spacjami powinny być otoczone cudzysłowamiźródło
0,
jeden z twoich zakresów:u=[L(r,i)for i in range(0,T(r))]
=>u=[L(r,i)for i in range(T(r))]
.S=map(str.lower,input())
dla -5 bajtów