Annulla unione di un elenco


14

introduzione

Molti di voi hanno familiarità con l' algoritmo di ordinamento unione per ordinare un elenco di numeri. Come parte dell'algoritmo, si scrive una funzione di supporto chiamata mergeche combina due elenchi ordinati in un elenco ordinato. Nello pseudocodice simile a Python, la funzione di solito assomiglia a questa:

function merge(A, B):
  C = []
  while A is not empty or B is not empty:
    if A is empty:
      C.append(B.pop())
    else if B is empty or A[0] ≤ B[0]:
      C.append(A.pop())
    else:
      C.append(B.pop())
  return C

L'idea è di continuare a far apparire il più piccolo dei primi elementi di Ae Bfino a quando entrambi gli elenchi sono vuoti, e raccogliere i risultati C. Se Ae Bsono entrambi ordinati, allora lo è anche C.

Al contrario, se Cè un elenco ordinato, e abbiamo diviso in due qualsiasi sottosequenze Ae B, quindi Ae Bsono anche ordinate e merge(A, B) == C. È interessante notare che questo non Cvale necessariamente se non è ordinato, il che ci porta a questa sfida.

Ingresso

Il tuo input è una permutazione dei primi 2*nnumeri interi non negativi [0, 1, 2, ..., 2*n-1]per alcuni n > 0, dato come un elenco C.

Produzione

L'output deve essere un valore veritiero se esistono due elenchi Ae Bdi lunghezza ntale C == merge(A, B)e un valore errato in caso contrario. Poiché l'input non contiene duplicati, non devi preoccuparti di come i legami vengono interrotti nella mergefunzione.

Regole e bonus

È possibile scrivere una funzione o un programma completo. Vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Si noti che non è necessario calcolare gli elenchi Ae Bnelle istanze "sì". Tuttavia, se effettivamente produci gli elenchi, ricevi un bonus del -20% . Per richiedere questo bonus, devi produrre solo una coppia di liste, non tutte le possibilità. Per rendere questo bonus più facile da rivendicare in linguaggi fortemente tipizzati, è consentito produrre una coppia di liste vuote nelle istanze "no".

La forzatura bruta non è vietata, ma c'è un bonus del -10% per il calcolo di tutti gli ultimi quattro casi di test in meno di 1 secondo in totale.

Casi test

Viene fornito un solo output possibile nelle istanze "yes".

[1,0] -> False
[0,1] -> [0] [1]
[3,2,1,0] -> False
[0,3,2,1] -> False
[0,1,2,3] -> [0,1] [2,3]
[1,4,0,3,2,5] -> False
[4,2,0,5,1,3] -> [4,2,0] [5,1,3]
[3,4,1,2,5,0] -> [4,1,2] [3,5,0]
[6,2,9,3,0,7,5,1,8,4] -> False
[5,7,2,9,6,8,3,4,1,0] -> False
[5,6,0,7,8,1,3,9,2,4] -> [6,0,8,1,3] [5,7,9,2,4]
[5,3,7,0,2,9,1,6,4,8] -> [5,3,7,0,2] [9,1,6,4,8]
[0,6,4,8,7,5,2,3,9,1] -> [8,7,5,2,3] [0,6,4,9,1]
[9,6,10,15,12,13,1,3,8,19,0,16,5,7,17,2,4,11,18,14] -> False
[14,8,12,0,5,4,16,9,17,7,11,1,2,10,18,19,13,15,6,3] -> False
[4,11,5,6,9,14,17,1,3,15,10,12,7,8,0,18,19,2,13,16] -> [4,17,1,3,15,10,12,7,8,0] [11,5,6,9,14,18,19,2,13,16]
[9,4,2,14,7,13,1,16,12,11,3,8,6,15,17,19,0,10,18,5] -> [9,4,2,16,12,11,3,8,6,15] [14,7,13,1,17,19,0,10,18,5]

Risposte:


3

Pyth, 39 * 0.9 * 0.8 = 28.08

#aY->QxQeS-QsY&YsY)KfqylTlQmsdty_Y%tlKK

Questo programma vongola tutti e due i bonus. Stampa una coppia di elenchi, se è possibile l'annullamento della fusione, altrimenti un elenco vuoto, che è un valore falso in Pyth (e Python).

Input:  [5,3,7,0,2,9,1,6,4,8]
Output: ([9, 1, 6, 4, 8], [5, 3, 7, 0, 2])
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

Puoi provarlo online , ma potrebbe essere un po 'più lento della versione offline. La versione offline risolve ciascuno dei casi di test in <0,15 secondi sul mio laptop.

Probabilmente (una delle) prime volte, una soluzione Pyth utilizza attivamente Eccezioni (ha salvato almeno 1 carattere). Utilizza la stessa idea della soluzione di Peter Taylor.

                         preinitialisations: Q = input(), Y = []
#                 )     while 1: (infinite loop)
        eS-QsY             finds the biggest, not previous used, number
      xQ                   finds the index
    >Q                     all elements from ... to end
   -          &YsY         but remove all used elements
 aY                        append the resulting list to Y

When all numbers are used, finding the biggest number fails, 
throws an exception and the while loop ends.  
This converts [5,3,7,0,2,9,1,6,4,8] to [[9, 1, 6, 4, 8], [7, 0, 2], [5, 3]]

        msdty_Y  combine the lists each for every possible subset of Y (except the empty subset)
 fqylTlQ         and filter them for lists T with 2*len(T) == len(Q)
K                and store them in K

%tlKK        print K[::len(K)-1] (prints first and last if K, else empty list)

Pyth, 30 * 0.9 = 27.0

Non ho davvero provato a risolverlo senza stampare gli elenchi risultanti. Ma ecco una soluzione rapida basata sul codice sopra.

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

Ho praticamente rimosso solo la dichiarazione di stampa. L'output è piuttosto brutto però.

Input:  [0,1,2,3]
Output: [[[3], [2]], [[3], [1]], [[2], [1]], [[3], [0]], [[2], [0]], [[1], [0]]] (truthy value)
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

Provalo online .


Potresti scoprire che invece di stampare (K[0], Q-K[0])puoi stampare (K[0], K[-1]). Non so se ciò darebbe un risparmio, però.
Peter Taylor,

@PeterTaylor grazie, risparmiato 2 caratteri.
Jakube,

@PeterTaylor e anche altri 2 caratteri, se stampo K[::len(K)-1].
Jakube,

4

GolfScript (35 * 0.9 = 31.5)

{.$-1>/~,)\.}do;]1,\{{1$+}+%}/)2/&,

La demo online è piuttosto lenta: sul mio computer, esegue tutti i test in meno di 0,04 secondi, quindi pretendo la riduzione del 10%.

Spiegazione

Il suffisso di C che inizia con il numero più grande in C deve provenire dallo stesso elenco. Quindi questo ragionamento può essere applicato a (suffisso C), in modo che il problema si riduca alla somma dei sottoinsiemi.


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.