Costruzione del sottostrato massimo


18

In questa sfida, hai superato due cose:

  1. Una lunghezza di stringa, N
  2. Un elenco di stringhe, Lognuna con un valore in punti assegnato. Qualsiasi stringa che non viene passata ha un valore in punti pari a 0

È necessario costruire una stringa di lunghezza in modo Ntale che la somma di tutti i punti di sottostringa sia la più grande possibile.

Per esempio:

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

dovrebbe produrre

ABCDG

Perché le due sottostringhe con punti ( ABCe CDG) hanno un totale di 5 punti e nessuna altra costruzione possibile può dare 5 o più punti.

I sottostringhi possono essere utilizzati più volte in una stringa e possono sovrapporsi. Puoi presumere che i punti saranno sempre positivi, le lunghezze della sottostringa saranno comprese tra 1 e lunghezze di Ncaratteri, e questo N > 0. Se le costruzioni multiple sono massime, stampane una qualsiasi.

Il programma deve essere eseguito in un periodo di tempo ragionevole (non più di un minuto per ciascuno degli esempi):

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

Questo è un , quindi prepara la tua risposta più breve nella tua lingua preferita!


Dobbiamo usare il tuo formato di input esatto o possiamo usare qualsiasi formato di input conveniente per la nostra lingua?
flawr

@flawr qualsiasi metodo di input conveniente va bene (dizionario, stdin, parametri di funzione)
Nathan Merrill

La DEFtupla manca una virgola
isaacg il

Ho una soluzione perfettamente bella, ma è troppo lenta per l'ultimo caso di test.
Isaacg,

1
@isaacg Ho una soluzione elegante, purtroppo questo commento è troppo piccolo per contenerlo. (
No

Risposte:


1

Python 2.7, 503 byte

Questo non è particolarmente golfato, né è particolarmente efficiente; è solo un elenco relativamente condensato di stringhe fattibili che sono forzate. Non penso che sarebbe troppo difficile creare un euristico ammissibile da usare con A *, che probabilmente sarebbe un po 'più veloce. Non mi sono preoccupato di farlo, però, perché questo metodo risolve tutti gli esempi in circa 47 secondi sul mio laptop.

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

Per testarlo:

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)

Spiegazione

La vfunzione calcola semplicemente il valore di una determinata stringa cercando tutte le occorrenze delle sottostringhe in L. La mfunzione enumera tutte le stringhe di lunghezza ncon il prefisso eche può essere generato dalle sottostringhe in l. msi chiama ricorsivamente; la prima chiamata dovrebbe passare ''per e. Per esempio:

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

La pfunzione scorre semplicemente attraverso tutte le stringhe possibili (come elencate da m) e restituisce quella con il valore più alto (come determinato da v).

Si noti che la mfunzione in realtà dà la priorità all'enumerazione ordinando in base ai valori delle sottostringhe. Ciò risulta inutile per garantire l'ottimalità e ostacola effettivamente un po 'l'efficienza; Potrei salvare circa 20 byte rimuovendolo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.