Annuler la fusion d'une liste

14

introduction

La plupart d'entre vous connaissent l' algorithme de tri par fusion pour trier une liste de nombres. Dans le cadre de l'algorithme, on écrit une fonction d'aide appelée mergequi combine deux listes triées en une seule liste triée. Dans un pseudocode de type Python, la fonction ressemble généralement à ceci:

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'idée est de continuer à faire apparaître le plus petit des premiers éléments de Aet Bjusqu'à ce que les deux listes soient vides, et de collecter les résultats dans C. Si Aet Bsont tous deux triés, alors il en est de même C.

Inversement, si Cest une liste triée, et nous la divisons en deux sous-séquences Aet B, puis Aet Bsont également triées et merge(A, B) == C. Fait intéressant, cela ne tient pas nécessairement si Cn'est pas trié, ce qui nous amène à ce défi.

Contribution

Votre entrée est une permutation des premiers 2*nentiers non négatifs [0, 1, 2, ..., 2*n-1]pour certains n > 0, donnée sous forme de liste C.

Production

Votre sortie doit être une valeur véridique s'il existe deux listes Aet Bde longueur ntelle que C == merge(A, B), et une valeur fausse sinon. Étant donné que l'entrée ne contient aucun doublon, vous n'avez pas à vous soucier de la façon dont les liens sont rompus dans la mergefonction.

Règles et bonus

Vous pouvez écrire soit une fonction soit un programme complet. Le nombre d'octets le plus bas gagne et les failles standard sont interdites.

Notez que vous n'êtes pas obligé de calculer les listes Aet Bdans les instances "oui". Cependant, si vous affichez réellement les listes, vous recevez un bonus de -20% . Pour réclamer ce bonus, vous devez générer une seule paire de listes, pas toutes les possibilités. Pour rendre ce bonus plus facile à réclamer dans des langues fortement typées, il est permis de sortir une paire de listes vides dans les instances "non".

Le forçage brutal n'est pas interdit, mais il y a un bonus de -10% pour le calcul des quatre derniers cas de test en moins d'une seconde au total.

Cas de test

Une seule sortie possible est donnée dans les instances "oui".

[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]
Zgarb
la source

Réponses:

3

Pyth, 39 * 0,9 * 0,8 = 28,08

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

Ce programme palourde les deux bonus. Il imprime une paire de listes, si la fusion est possible, sinon une liste vide, qui est une valeur fausse en Pyth (et 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)

Vous pouvez le tester en ligne , mais il peut être un peu plus lent que la version hors ligne. La version hors ligne résout chacun des cas de test en moins de 0,15 seconde sur mon ordinateur portable.

Probablement (l'une des) la première fois, une solution Pyth utilise activement des exceptions (elle a enregistré au moins 1 caractère). Il utilise la même idée que la solution de 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

Je n'ai pas vraiment essayé de le résoudre sans imprimer les listes résultantes. Mais voici une solution rapide basée sur le code ci-dessus.

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

J'ai simplement supprimé l'instruction print. La sortie est cependant assez moche.

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)

Essayez-le en ligne .

Jakube
la source
Vous pouvez constater qu'au lieu d'imprimer, (K[0], Q-K[0])vous pouvez imprimer (K[0], K[-1]). Je ne sais pas si cela donnerait une économie, cependant.
Peter Taylor
Merci @PeterTaylor, enregistré 2 caractères.
Jakube
@PeterTaylor et même 2 autres caractères, si j'imprime K[::len(K)-1].
Jakube
4

GolfScript (35 * 0,9 = 31,5)

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

La démo en ligne est assez lente: sur mon ordinateur, elle exécute tous les tests en moins de 0,04 seconde, donc je réclame la réduction de 10%.

Explication

Le suffixe de C qui commence par le plus grand nombre en C doit provenir de la même liste. Ensuite, ce raisonnement peut être appliqué à (suffixe C), de sorte que le problème se réduit à la somme des sous-ensembles.

Peter Taylor
la source
2

APL, 62 50 44 * 90% = 39,6

{(l÷2)⌷↑(⊢∨⌽)/(2-/(1,⍨⍵≥⌈\⍵)/⍳l+1),⊂l=⍳l←⍴⍵}

Essayez-le ici.

jimmy23013
la source