Hủy hợp nhất một danh sách


14

Giới thiệu

Hầu hết các bạn đều quen thuộc với thuật toán sắp xếp hợp nhất để sắp xếp danh sách các số. Là một phần của thuật toán, người ta viết một hàm trợ giúp được gọi là mergekết hợp hai danh sách được sắp xếp thành một danh sách được sắp xếp. Trong mã giả giống như Python, hàm thường trông giống như thế này:

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

Ý tưởng là tiếp tục xuất hiện các phần tử đầu tiên nhỏ hơn ABcho đến khi cả hai danh sách đều trống và thu thập kết quả vào C. Nếu ABđược cả hai sắp xếp, thì cũng vậy C.

Ngược lại, nếu Clà một danh sách được sắp xếp, và chúng tôi chia nó thành bất kỳ hai subsequences AB, sau đó ABcũng đều được sắp xếp và merge(A, B) == C. Thật thú vị, điều này không nhất thiết phải giữ nếu Ckhông được sắp xếp, điều này đưa chúng ta đến thử thách này.

Đầu vào

Đầu vào của bạn là một hoán vị của các 2*nsố nguyên không âm đầu tiên [0, 1, 2, ..., 2*n-1]cho một số n > 0, được đưa ra dưới dạng danh sách C.

Đầu ra

Đầu ra của bạn sẽ là một giá trị trung thực nếu tồn tại hai danh sách ABđộ dài nsao cho C == merge(A, B)giá trị giả mạo khác. Vì đầu vào không chứa các bản sao, bạn không phải lo lắng về việc các mối quan hệ bị phá vỡ trong mergechức năng.

Quy tắc và tiền thưởng

Bạn có thể viết một hàm hoặc một chương trình đầy đủ. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

Lưu ý rằng bạn không bắt buộc phải tính toán các danh sách ABtrong trường hợp "có". Tuy nhiên, nếu bạn thực sự xuất danh sách, bạn sẽ nhận được tiền thưởng -20% . Để nhận phần thưởng này, bạn phải xuất ra chỉ một cặp danh sách, không phải tất cả các khả năng. Để làm cho phần thưởng này dễ dàng hơn để yêu cầu bằng các ngôn ngữ được gõ mạnh, nó được phép xuất ra một cặp danh sách trống trong các trường hợp "không".

Buộc cưỡng bức không bị cấm, nhưng có phần thưởng -10% cho việc tính toán tất cả bốn trường hợp thử nghiệm gần đây trong tổng số dưới 1 giây.

Các trường hợp thử nghiệm

Chỉ có một đầu ra có thể được đưa ra trong các trường hợp "có".

[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]

Câu trả lời:


3

Bình, 39 * 0,9 * 0,8 = 28,08

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

Chương trình này nghêu cả hai phần thưởng. Nó in một cặp danh sách, nếu không hợp nhất là có thể, ngoài ra một danh sách trống, là giá trị giả trong Pyth (và 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)

Bạn có thể kiểm tra trực tuyến , nhưng nó có thể chậm hơn một chút so với phiên bản ngoại tuyến. Phiên bản ngoại tuyến giải quyết từng trường hợp thử nghiệm trong <0,15 giây trên máy tính xách tay của tôi.

Có lẽ (một trong) lần đầu tiên, một giải pháp Pyth sử dụng Ngoại lệ tích cực (nó đã lưu ít nhất 1 char). Nó sử dụng ý tưởng tương tự như giải pháp của 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)

Bình thường, 30 * 0,9 = 27,0

Tôi đã không thực sự cố gắng giải quyết nó mà không in các danh sách kết quả. Nhưng đây là một giải pháp nhanh chóng dựa trên mã ở trên.

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

Tôi về cơ bản chỉ loại bỏ các tuyên bố in. Đầu ra là khá xấu mặc dù.

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)

Hãy thử trực tuyến .


Bạn có thể thấy rằng thay vì in (K[0], Q-K[0])bạn có thể in (K[0], K[-1]). Tôi không biết liệu điều đó sẽ tiết kiệm, mặc dù.
Peter Taylor

@PeterTaylor cảm ơn, đã lưu 2 ký tự.
Jakube

@PeterTaylor và thậm chí 2 ký tự nữa, nếu tôi in K[::len(K)-1].
Jakube

4

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

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

Bản demo trực tuyến khá chậm: trên máy tính của tôi, nó chạy tất cả các bài kiểm tra trong vòng dưới 0,04 giây, vì vậy tôi yêu cầu giảm 10%.

Giải trình

Hậu tố của C bắt đầu bằng số lớn nhất trong C phải xuất phát từ cùng một danh sách. Sau đó, lý do này có thể được áp dụng cho (C - hậu tố), để vấn đề giảm xuống tổng tập hợp con.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.