ライブラリを検索するcode-golferの方法


15

チャレンジ:

私の音楽コレクションには何千もの曲があり、幸運なことに、私のお気に入りのプレーヤーには検索機能があります。また、素晴らしい思い出があります。コレクションのすべての曲のタイトルを思い出すことができます。しかし、私はとても怠け者で、タイプするのが好きではありません。それぞれの余分なキーストロークは面倒です!

  • 1曲を分離するために検索する必要がある最短文字列は何ですか?検索時に入力を最小限に抑えるために使用できるキーのリストを記憶してください。

これはなので、最短のコードが優先されます。


ルール:

曲のタイトルの入力リストが与えられたら、次の制約に従って検索キーのリストを生成します。

  1. 各曲のタイトルには検索キーが必要です。
  2. 出力リストの文字の総数は、できるだけ少なくする必要があります。
  3. 私の好きな音楽プレーヤーはfoob​​ar2000です。
    • 検索機能では大文字と小文字は区別されません。(appleはと同じですaPpLE)。
    • 各検索キーは、スペースで区切られた任意の順序の1つ以上の「単語」で構成する必要があります。
      • 各単語は、対応する曲のタイトルのサブストリングである必要があります。
      • 同じ部分文字列が複数回指定されている場合、対応する曲のタイトルで何度も発生する必要があります。
      • 部分文字列自体にスペースが含まれる場合、その部分文字列を引用符で囲む必要があります。

ヒント:

  • 多くの場合、一部の曲のタイトルには、ルール2を満たす複数の検索キーがあります。このような場合、いずれかのキーが機能しますが、すべてをリストするとブラウニーポイントが得られます。
  • 入力リストはASCII文字のみであると想定できますが、ブラウニーポイントはUTF-8互換性のために与えられます。
  • ルール3は従うのが難しかったですか?仕組みは次のとおりです。


例:

私の音楽コレクションが、マイケルジャクソンのOff the WallThrilerの2枚のアルバムだけで構成されている場合:

上記のリストを使用して、プログラムをテストできます。次に、2番目のリストの未加工バージョンを示します。

["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"]
ジョナサンアラン

...しかし、サブストリング自体にスペースが許可されていない場合、彼らは何をすべきか/可能性があります-すべての単語が衝突することに注意してください。
ジョナサンアラン

なぜ生のバージョンがネタバレなのですか?
リーキー修道女

回答:


4

Python 2、556バイト

オンラインでお試しください。

-10バイト、@ Riker、@ ovsのおかげ

すべてがうまくいくように、2、3泊しました。
曲名、検索キーの配列、検索キーの長さを組み合わせて出力します(スペースと引用符を含む)

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のすべての可能な部分文字列を評価します。 create
eval(...)コマンド可能であれば、すべてのインデックスから長さのzip(s,s[1:],s[2:],...,s[n:])
部分文字列を作成します。そのため、bu、ud、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)が一意の曲名用であるかどうかを確認するフィルター。
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))]

最初のラムダ関数を使用して、現在の文字列に対して可能なすべてのキーの組み合わせ(可能なすべての長さ)を取得します。


生成されたすべてのキーを調べて、それらを次の再帰ステップに個別に渡すサイクルの2つ。j文字列の末尾の文字列を正しくスライスするには、キーの位置()が必要ですr[j+T(u[i][j]):]
スライスは、現在のキーが終了するところから始まる文字列を提供するため、重複することはありません。
場所が不明な場合、等しいキーですべてが台無しになります。


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

単なるよりもはるかに長いですyが、スペースのあるキーは引用符で囲む必要があります


これは素晴らしいです。ルール3を正しく取得した最初の人です!
あやね

1
ところで、0,範囲の1つを削除することで2バイトを削ることができるはずです:u=[L(r,i)for i in range(0,T(r))]=> u=[L(r,i)for i in range(T(r))]
-notjagan

1
さらに数バイト節約できます。出力では、入力文字列と出力文字列のサイズを表示する必要はありません。
あやね

@彩音Mありがとう!範囲と出力からこの数バイトを削除しました。
デッドポッサム

1
S=map(str.lower,input())-5バイトの場合
-ovs
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.