最大部分文字列の構築


18

この課題では、次の2つのことが渡されます。

  1. 文字列の長さ、 N
  2. 文字列のリストL、それぞれに割り当てられたポイント値があります。渡されない文字列のポイント値は0です

Nすべてのサブストリングポイントの合計ができるだけ大きくなるような長さのストリングを作成する必要があります。

例えば:

5 [("ABC", 3), ("DEF", 4), ("CDG", 2)]

出力する必要があります

ABCDG

ポイント(ABCおよびCDG)を持つ2つの部分文字列は合計5ポイントであり、他の可能な構造では5ポイント以上を与えることができないためです。

部分文字列は、文字列内で複数回使用でき、重複する場合があります。ポイントは常に正であり、部分文字列の長さは1からN文字長の間であると仮定できN > 0ます。複数の構成が最大の場合、それらのいずれかを印刷します。

プログラムは妥当な時間内に実行する必要があります(各例で1分以内):

1 [("A", 7), ("B", 4), ("C", 100)]     => C
2 [("A", 2), ("B", 3), ("AB", 2)]      => AB
2 [("A", 1), ("B", 2), ("CD", 3)]      => BB
2 [("AD", 1), ("B", 2), ("ZB", 3)]     => ZB
3 [("AB", 2), ("BC", 1), ("CA", 3)]    => CAB
3 [("ABC", 4), ("DEF", 4), ("E", 1)]   => DEF
4 [("A", 1), ("BAB", 2), ("ABCD", 3)]  => AAAA or ABAB or BABA or ABCD
5 [("A", 1), ("BAB", 2), ("ABCD", 3)]  => BABCD or BABAB
5 [("ABC", 3), ("DEF", 4), ("CDG", 2)] => ABCDG
5 [("AB", 10), ("BC", 2), ("CA", 2)]   => ABCAB
6 [("AB", 10), ("BC", 2), ("CA", 2)]   => ABABAB
8 [("AA", 3), ("BA", 5)]               => BAAAAAAA
10 [("ABCDE", 19), ("ACEBD",  18), ("ABEDC", 17), ("BCEDA", 16), ("EBDAC", 15), ("BACD", 14), ("CADB", 13), ("ABDC", 12), ("CABD", 11), ("EBDC", 10), ("ACE", 9), ("CBA", 8), ("AEC", 7), ("BE", 6), ("AE", 5), ("DC", 4), ("BA", 3), ("A", 2), ("D", 1)]
=> ACEBDACEBD

これはですので、お気に入りの言語で最短回答を準備してください!


正確な入力形式を使用する必要がありますか、それとも言語に便利な入力形式を使用できますか?
flawr

@flawr便利な入力方法であれば問題ありません(辞書、標準入力、関数パラメーター)
Nathan Merrill

DEFコンマ不足しているタプル
isaacg

私は完全に素晴らしい解決策を持っていますが、最後のテストケースには遅すぎます。
isaacg

1
@isaacgエレガントな解決策がありますが、残念ながらこのコメントは小さすぎて収まりません。(私は、フェルマーを引用したくありませんでした。)
orlp

回答:


1

Python 2.7、503バイト

これは特にゴルフではなく、特に効率的でもありません。ブルートフォースされた実行可能な文字列の比較的凝縮された列挙にすぎません。A *で使用できる許容可能なヒューリスティックを作成するのはそれほど難しくないと思いますが、これはおそらく少し速くなります。しかし、この方法はラップトップで約47秒ですべての例を解決するので、私はそれを気にしませんでした。

import re
v=lambda l,s:sum([len([m.start() for m in re.finditer('(?=%s)'%u,s)])*v for u,v in l])
def m(n,l,e):
 if len(e)==n:
  yield e
 else:
  u=1
  for s,v in sorted(l,key=lambda j:j[1],reverse=True):
   for i in range(len(s)-1,0,-1):
    if len(e)+len(s)-i <= n and e.endswith(s[:i]):
     for r in m(n,l,e+s[i:]):
      u=0;yield r
   if len(e)+len(s)<=n:
    for r in m(n,l,e+s):
     u=0;yield r
  if u:
   yield e
def p(n,l):
 b,r=-1,0
 for s in m(n,l,''):
  a=v(l,s)
  if a>b:b,r=a,s
 return r

テストするには:

if __name__ == "__main__":
    for n, l in [
            (1, [("A", 7), ("B", 4), ("C", 100)]),     # => C
            (2, [("A", 2), ("B", 3), ("AB", 2)]),      # => AB
            (2, [("A", 1), ("B", 2), ("CD", 3)]),      # => BB
            (2, [("AD", 1), ("B", 2), ("ZB", 3)]),     # => ZB
            (3, [("AB", 2), ("BC", 1), ("CA", 3)]),    # => CAB
            (3, [("ABC", 4), ("DEF", 4), ("E", 1)]),   # => DEF
            (4, [("A", 1), ("BAB", 2), ("ABCD", 3)]),  # => AAAA or ABAB or BABA or ABCD
            (5, [("A", 1), ("BAB", 2), ("ABCD", 3)]),  # => BABCD or BABAB
            (5, [("ABC", 3), ("DEF", 4), ("CDG", 2)]), # => ABCDG
            (5, [("AB", 10), ("BC", 2), ("CA", 2)]),   # => ABCAB
            (6, [("AB", 10), ("BC", 2), ("CA", 2)]),   # => ABABAB
            (8, [("AA", 3), ("BA", 5)]),               # => BAAAAAAA
            (10, [("ABCDE", 19), ("ACEBD",  18), ("ABEDC", 17), ("BCEDA", 16), ("EBDAC", 15), ("BACD", 14), ("CADB", 13), ("ABDC", 12), ("CABD", 11), ("EBDC", 10), ("ACE", 9), ("CBA", 8), ("AEC", 7), ("BE", 6), ("AE", 5), ("DC", 4), ("BA", 3), ("A", 2), ("D", 1)]) # => ACEBDACEBD
    ]:
        print p(n, l)

説明

v関数は単にLにサブストリングのすべての出現を検索することにより、指定された文字列の値を算出するm関数は、長さのすべての文字列を列挙しn接頭辞eでサブストリングから生成することができますlm再帰的に自分自身を呼び出します。最初の呼び出しはに渡す必要があります''についてe。例えば:

>>> for s in m(4, [("A", 1), ("BAB", 2), ("ABCD", 3)], ''):print s
ABCD
BABA
ABCD
ABAB
AAAA

このp関数は、可能なすべての文字列(によって列挙されるm)を単にループし、最高の値を持つ文字列を返します(v

m関数は、サブストリングの値に基づいてソートすることにより、実際に列挙を優先することに注意してください。これは最適性を確保するために不要であることが判明し、実際には効率を少し妨げます。削除することで、約20バイト程度節約できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.