Odzyskaj listę

14

Wprowadzenie

Większość z was zna algorytm sortowania scalającego do sortowania listy liczb. W ramach algorytmu zapisuje się funkcję pomocniczą, mergektóra łączy dwie posortowane listy w jedną posortowaną listę. W pseudokodzie podobnym do Pythona funkcja zwykle wygląda mniej więcej tak:

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

Chodzi o to, aby wyświetlać mniejszy z pierwszych elementów Ai Bdopóki obie listy nie będą puste, i gromadzić wyniki C. Jeśli Ai Boba są posortowane, to tak też jest C.

I odwrotnie, jeśli Cjest lista sortowane, a my podzielić ją na dowolnych dwóch podciągów Ai B, następnie A, a Btakże sortowane i merge(A, B) == C. Co ciekawe, nie jest to konieczne, jeśli Cnie zostanie posortowane, co prowadzi nas do tego wyzwania.

Wejście

Twoje dane wejściowe są permutacją pierwszych 2*nnieujemnych liczb całkowitych [0, 1, 2, ..., 2*n-1]dla niektórych n > 0, podane jako lista C.

Wynik

Twój wynik będzie prawdziwą wartością, jeśli istnieją dwie listy Ai takiej Bdługości , a fałszem w przeciwnym razie. Ponieważ dane wejściowe nie zawierają duplikatów, nie musisz się martwić o zerwanie powiązań w funkcji.nC == merge(A, B)merge

Zasady i bonusy

Możesz napisać funkcję lub pełny program. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Należy pamiętać, że nie jest wymagane obliczanie list Aoraz Bw przypadkach „tak”. Jeśli jednak faktycznie wyślesz listy, otrzymasz premię w wysokości -20% . Aby skorzystać z tej premii, musisz wygenerować tylko jedną parę list, a nie wszystkie możliwości. Aby ułatwić ubieganie się o ten bonus w silnie typowanych językach, dozwolone jest generowanie pary pustych list w instancjach „nie”.

Brutalne wymuszanie nie jest zabronione, ale istnieje premia w wysokości -10% za obliczenie wszystkich czterech ostatnich przypadków testowych w sumie poniżej 1 sekundy.

Przypadki testowe

Tylko jedno możliwe wyjście jest podawane w instancjach „tak”.

[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
źródło

Odpowiedzi:

3

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

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

Ten program zawiera wszystkie dwa bonusy. Wyświetla parę list, jeśli możliwe jest ich scalenie, w przeciwnym razie pusta lista, która jest wartością falsy w Pyth (i 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)

Możesz to przetestować online , ale może być nieco wolniejszy niż wersja offline. Wersja offline rozwiązuje każdy z przypadków testowych na moim laptopie w <0,15 sekundy.

Prawdopodobnie (jeden) po raz pierwszy rozwiązanie Pyth aktywnie korzysta z wyjątków ( zapisało co najmniej 1 znak). Wykorzystuje ten sam pomysł, co rozwiązanie Petera Taylora.

                         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

Naprawdę nie próbowałem go rozwiązać bez drukowania wynikowych list. Ale oto szybkie rozwiązanie oparte na powyższym kodzie.

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

Zasadniczo usunąłem tylko instrukcję print. Wynik jest jednak dość brzydki.

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)

Wypróbuj online .

Jakube
źródło
Może się okazać, że zamiast drukowania (K[0], Q-K[0])możesz wydrukować (K[0], K[-1]). Nie wiem jednak, czy to dałoby oszczędności.
Peter Taylor,
@PeterTaylor dzięki, zapisano 2 znaki.
Jakube,
@PeterTaylor i jeszcze 2 znaki, jeśli wydrukuję K[::len(K)-1].
Jakube,
4

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

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

Demo on-line jest dość powolna: na moim komputerze, działa we wszystkich testach w ramach 0,04 sekundy, więc domagać się 10% zniżki.

Wyjaśnienie

Sufiks C rozpoczynający się od największej liczby w C musi pochodzić z tej samej listy. Następnie to rozumowanie można zastosować do (sufiksu C), aby problem sprowadzał się do sumy podzbioru.

Peter Taylor
źródło
2

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

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

Wypróbuj tutaj.

jimmy23013
źródło