라이브러리를 검색하는 코드 골퍼 방식


15

도전:

음악 컬렉션에 수천 곡의 노래가 있으며 운 좋게도 내가 좋아하는 플레이어에는 검색 기능이 있습니다. 또한 추억이 있습니다. 내 컬렉션에있는 모든 노래의 제목을 기억할 수 있습니다. 그러나 나는 매우 게으르고 타이핑하는 것을 좋아하지 않습니다. 각각의 추가 키 입력은 번거로운 일입니다!

  • 하나의 노래를 분리하기 위해 검색해야하는 가장 짧은 문자열은 무엇입니까? 검색 할 때 입력을 최소화하는 데 사용할 수있는 키 목록을 기억하도록 도와주세요!

이것은 이므로 가장 짧은 코드가 승리합니다.


규칙 :

노래 제목의 입력 목록이 제공되면 다음 제약 조건이 적용되는 검색 키 목록을 생성하십시오.

  1. 각 노래 제목에는 검색 키가 있어야합니다.
  2. 출력 목록의 총 문자 수는 가능한 한 적어야합니다.
  3. 내가 가장 좋아하는 음악 플레이어는 foobar2000입니다 .
    • 검색 기능은 대소 문자를 구분하지 않습니다. ( apple와 동일 aPpLE)
    • 각 검색 키는 공백으로 구분 된 순서대로 하나 이상의 "단어"로 구성되어야합니다.
      • 각 단어는 해당 노래 제목 의 하위 문자열 이어야합니다 .
      • 동일한 하위 문자열이 여러 번 지정된 경우 해당 노래 제목에서 여러 번 나타나야합니다.
      • 부분 문자열 자체에 공백이 있으면 해당 부분 문자열을 따옴표로 묶어야합니다.

힌트 :

  • 일부 노래 제목의 경우 규칙 2를 충족하는 여러 개의 검색 키가있는 경우가 종종 있습니다. 이러한 경우 하나의 키가 수행되지만 모두 나열 할 수있는 브라우니 포인트가 생깁니다.
  • 입력 목록은 ASCII 문자로만 가정되지만 UTF-8 호환성을 위해 브라우니 포인트가 부여됩니다.
  • 규칙 3을 따르기가 어려웠습니까? 작동 방식은 다음과 같습니다.


예:

내 음악 컬렉션이 두 개의 앨범으로 만 구성된 경우 Michael Jackson의 Off the WallThriler는 다음 과 같습니다 .

위의 목록을 사용하여 프로그램을 테스트 할 수 있습니다. 두 번째 목록의 원시 버전은 다음과 같습니다.

["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
키에 여러 문자열이 필요한 예가 있습니까?
Jonathan Allan

1
어때요 ["Wanta Be A Wanna B","Wanta Bea A Wanna B","Wanna Be A Wanna Bea"]?
Jonathan Allan

...하지만 하위 문자열 자체에 공백이 없으면 모든 단어가 충돌한다는 점에 유의하십시오.
Jonathan Allan

왜 스포일러에 원시 버전이 있습니까?
Leaky Nun

답변:


4

파이썬 2, 556 바이트

온라인으로 사용해보십시오.

@Riker, @ovs 덕분에 -10 바이트

모든 것이 작동하도록 저녁을 먹었습니다.
노래 이름, 검색 키 배열 및 검색 키 길이 결합 (공백 및 따옴표 포함)

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)

문자열 길이의 가능한 모든 하위 문자열을 평가합니다.
eval(...)작성 명령 가능하면 모든 색인에서 zip(s,s[1:],s[2:],...,s[n:])
길이의 하위 문자열을 작성 합니다. 그래서 대한 과 가 생산됩니다 BU, 총을 쏘고, DD를nss='budd'n='2'


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)가 고유 한 노래 이름을위한 것인지 확인하는 필터입니다.
예에서 [ 'nn', 'nn']과 같이 여러 개의 동일한 키에 대해 re.sub가 다시 시도됩니다.


내부 함수 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을 올바르게 얻는 첫 번째 사람입니다!
ayane

1
그건 그렇고, 0,범위 중 하나를 제거하여 2 바이트를 줄일 수 있어야 합니다 : u=[L(r,i)for i in range(0,T(r))]=> u=[L(r,i)for i in range(T(r))].
notjagan

1
몇 바이트를 더 절약 할 수 있습니다. 출력에서 ​​입력 문자열과 출력 문자열의 크기를 표시하지 않아도됩니다.
ayane

@ 彩 音 M 감사합니다! 범위와 출력 에서이 몇 바이트를 잘라 냈습니다.
죽은 Possum

1
S=map(str.lower,input())-5 바이트
ovs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.