Làm cho các bộ tách rời mà không làm trống chúng


8

Giả sử bạn có một bộ các số nguyên. Có thể một số bộ sẽ chồng lấp (tức là các phần tử chia sẻ). Bạn có thể thoát khỏi sự chồng chéo bằng cách xóa các phần tử khỏi các tập hợp, nhưng sau đó một số trong số chúng có thể kết thúc trống; đó sẽ là một sự xấu hổ Chúng ta có thể làm cho tất cả các bộ tách rời nhau mà không làm trống bất kỳ bộ nào không?

Lưu ý rằng trong tình huống này, không bao giờ có bất kỳ lý do nào để để lại nhiều phần tử trong một tập hợp, vì vậy vấn đề này luôn có thể được giải quyết bằng cách giảm mỗi bộ thành chỉ một phần tử. Đó là phiên bản của vấn đề chúng tôi đang giải quyết ở đây.

Nhiệm vụ

Viết chương trình hoặc hàm, như sau:

Đầu vào : Một danh sách các bộ số nguyên.

Đầu ra : Một danh sách các số nguyên, có cùng độ dài với đầu vào, trong đó:

  • Tất cả các số nguyên trong đầu ra là khác biệt; và
  • Mỗi số nguyên trong đầu ra là một phần tử của tập hợp đầu vào tương ứng.

Làm rõ

  • Bạn có thể biểu diễn một tập hợp dưới dạng danh sách nếu bạn muốn (hoặc bất cứ điều gì phù hợp với ngôn ngữ của bạn), bỏ qua thứ tự các yếu tố.
  • Bạn không phải xử lý trường hợp không có giải pháp tồn tại (nghĩa là sẽ luôn có ít nhất một giải pháp).
  • Có thể có nhiều hơn một giải pháp. Thuật toán của bạn phải luôn tạo ra một giải pháp hợp lệ, nhưng được phép không đặc biệt (nghĩa là nó ổn nếu nó chọn một giải pháp hợp lệ khác nhau mỗi lần nó chạy).
  • Số lượng số nguyên riêng biệt xuất hiện trong đầu vào, n , sẽ bằng số lượng bộ trong đầu vào và để đơn giản, sẽ là các số nguyên từ 1 đến n bao gồm (vì giá trị thực của chúng không quan trọng). Tùy thuộc vào việc bạn có muốn khai thác sự thật này hay không.

Tủ thử

[{1,2},{1,3},{1,4},{3,4}] -> [2,3,1,4] or [2,1,4,3]
[{1,3},{1,2,4},{2,3},{3},{2,3,4,5}] -> [1,4,2,3,5]
[{1,3,4},{2,3,5},{1,2},{4,5},{4,5}] -> [1,3,2,4,5] or [3,2,1,4,5] or [1,3,2,5,4] or [3,2,1,5,4]

Điều kiện chiến thắng

Một chương trình đòi hỏi độ phức tạp thời gian tối ưu để giành chiến thắng, tức là nếu một thuật toán có độ phức tạp thời gian tốt hơn được tìm thấy, nó sẽ loại bỏ tất cả các mục chậm hơn. (Bạn có thể giả sử rằng các nội dung trong ngôn ngữ của bạn chạy càng nhanh càng tốt, ví dụ: bạn có thể giả sử rằng một nội dung sắp xếp chạy trong thời gian O (n log n). Tương tự, giả sử rằng tất cả các số nguyên có kích thước tương đương với n có thể được thêm, nhân, v.v. trong thời gian không đổi.)

Bởi vì độ phức tạp thời gian tối ưu có thể khá dễ dàng đạt được trong hầu hết các ngôn ngữ, do đó, người chiến thắng sẽ là chương trình ngắn nhất trong số những ngôn ngữ có độ phức tạp thời gian chiến thắng, được đo bằng byte.


Nếu nó không có ý nghĩa thì tại sao họ lại hiểu nó ở đây dreamincode.net/forums/topic/iêu
fred russell

@fredrussell có lẽ, chỉ là có thể, đó là về cách bạn giải thích nó chứ không phải về, ví dụ như ký hiệu trên hình ảnh?
NieDzejkob

7
@fredrussell giải thích của bạn về "thách thức" không rõ ràng và không được định dạng. Trên trang web này, bạn thường sẽ tìm thấy các câu hỏi được định dạng và đặt hàng chính xác, ví dụ: theo bố cục như "Đầu vào; Đầu ra; Quy tắc; Testcase", nhưng bạn không cung cấp bất cứ điều gì về điều đó. Ngoài ra, bạn không có tiêu chí chiến thắng có thể xác định người chiến thắng. Và sau sự xúc phạm của bạn, tôi không nghĩ có ai sẵn sàng giải quyết câu hỏi bây giờ. Ngay cả trên SO, bạn nên luôn luôn nhớ rằng những người trả lời đang làm điều này trong thời gian rảnh của họ, vì vậy bạn không nên thô lỗ như thế.
Luca H

1
@Arnauld mã nhanh nhất sẽ ngụ ý rằng nếu cả hai chúng ta đều viết thuật toán O (n), nhưng mã của bạn nhanh hơn 100 lần, thì bạn sẽ thắng. Nếu chúng ta chỉ yêu cầu độ phức tạp thời gian tối ưu thì không sao nếu mã của tôi chậm hơn 100 lần, miễn là nó nhỏ hơn một byte. Nhưng thách thức này có thể được tính là thuật toán nhanh nhất .
Misha Lavrov

2
Đây chính xác là vấn đề tìm kiếm một kết hợp đầy đủ trong biểu đồ lưỡng cực. Độ phức tạp thời gian của các thuật toán được biết đến nhiều nhất phụ thuộc vào mức độ lớn của các tập hợp so với số lượng tập hợp. Thử thách liên quan.
Zgarb

Câu trả lời:


2

Thạch , 8 byte

Œp⁼Q$ÐfḢ

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

Giải trình

Œp⁼Q$ÐfḢ  Main Link
Œp        Cartesian Product of the elements; all possible lists
     Ðf   Filter; keep elements that are
  ⁼Q$     Equal to themselves uniquified
      Ḣ   Take the first one

Vô cùng kém hiệu quả. Không triệu chứng ϴ(n^(n+1))theo Misha Lavrov; Tôi nghĩ nó đúng.


Tôi nghĩ rằng đây là ít nhất (n ^ n): kích thước tối đa có thể có của sản phẩm Cartesian.
Misha Lavrov

Chính xác hơn, (n ^ (n + 1)), vì kiểm tra "bằng với chính nó duy nhất" phải là ϴ (n) thời gian.
Misha Lavrov

@MishaLavrov À được rồi, cảm ơn.
HyperNeutrino

Hàm @HyperNeutrino uniquetrong kiểm tra O(n)ngăn chặn sử dụng Jelly ( x in s), mỗi người nên thực hiện O(n)theo trang này , do đó, Qnên có O(n^2)độ phức tạp trong trường hợp xấu nhất / trường hợp trung bình. Do đó, thuật toán là O(n^(n+2)). (duy nhất có thể O(n)trong trường hợp tất cả các phần tử đều bằng nhau, trong đó mỗi kiểm tra ngăn chặn chạy vào O(1)) --- Trên một ghi chú không liên quan, có thể thực hiện uniquetrong O(n)việc sử dụng setcấu trúc dữ liệu dựng sẵn của Python được đặt băm. Dù sao Jelly không được thiết kế để có hiệu quả.
dùng202729

2

Ngôn ngữ Wolfram (Mathicala) , 87 byte và (n 3 )

-Range[n=Length@#]/.Rule@@@FindIndependentEdgeSet[Join@@Table[-i->j,{i,n},{j,#[[i]]}]]&

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

Xây dựng một đồ thị hai phía có đỉnh ở một bên là những bộ (lập chỉ mục -1,-2,...,-n) và có đỉnh ở phía bên kia là những yếu tố 1,2,...,n, với một cạnh từ -iđến jkhi jđược chứa trong các ibộ -thứ. Tìm một kết hợp hoàn hảo trong biểu đồ này bằng cách sử dụng tích hợp. Sau đó liệt kê ra các yếu tố tương ứng -1,-2,...,-ntheo thứ tự đó trong kết hợp hoàn hảo.

Mathematica FindIndependentEdgeSetlà nút cổ chai ở đây; mọi thứ khác cần các thao tác O (n 2 ) để làm. Mathematica có thể sử dụng thuật toán Hungary , và vì vậy tôi sẽ cho rằng nó chạy trong thời gian ϴ (n 3 ) , mặc dù có thể Mathicala có một triển khai ngây thơ với độ phức tạp O (n 4 ).


Chà ... Mathicala rất tệ ở độ phức tạp hạn chế , không phải lần đầu tiên.
dùng202729


1

Toán học 39 byte

Last@Union[DeleteDuplicates/@Tuples@#]&

Về vấn đề phức tạp, tôi nghĩ nó phụ thuộc rất nhiều vào độ dài của mỗi danh sách con, cũng như thước đo mức độ phân biệt các danh sách con.

Vì vậy, tôi nghĩ thuật toán này là O (n Log n + n ^ 2 Log m) trong đó m có độ dài trung bình của mỗi danh sách con.

Một cái gì đó như thế này sẽ có độ phức tạp O (a ^ n) trong đó a> 1 là thước đo sự chồng chéo trong danh sách con:

(For[x={1,1},!DuplicateFreeQ@x,x=RandomChoice/@#];x)&

Khó có thể nói cái nào thực sự nhanh hơn mà không biết các thuộc tính của đầu vào có thể.


2
Các DeleteDuplicates /@ Tuples@#bước mất Θ (n ^ (n + 1)) thời gian bằng những lập luận tương tự như trong các giải pháp khác. Sau đó, Unioncó một danh sách độ dài n ^ n để sắp xếp, mất thời gian O (n ^ (n + 1) log (n)) - nhưng có lẽ nó nhanh hơn vì nhiều nhất là 2 ^ nn! các yếu tố trong danh sách đó là khác biệt. Dù bằng cách nào, độ phức tạp là (n ^ (n + 1)) cho đến một yếu tố log (n).
Misha Lavrov

Tôi nghĩ vấn đề này đòi hỏi một định nghĩa đa biến về ký hiệu O lớn để có bất kỳ ý nghĩa thực tế nào. Rõ ràng độ dài của danh sách con là vô cùng quan trọng.
Kelly Lowder

1
Giải thích của tôi về tuyên bố vấn đề là chỉ có sự phụ thuộc vào n (số lượng danh sách phụ) và chúng tôi giả sử trường hợp xấu nhất về độ dài của danh sách phụ. Trong mọi trường hợp, ngay cả khi mọi danh sách phụ có chiều dài 2, Tuples@#có kích thước 2 ^ n, vì vậy ước tính tiệm cận đầu tiên của bạn không thể đúng.
Misha Lavrov

Huh? Tại sao BigO đa biến có vấn đề? Nó đã được thực hiện tất cả các thời gian.
dùng202729

1

05AB1E , 13 byte, O (n! * N)

āœʒ‚øε`QO}P}н

Hãy thử trực tuyến! Giải trình:

ā               Make a range 1..n
 œ              Generate all permutations
  ʒ        }    Filter
   ‚ø           Zip with input
     ε   }      Loop over sets
      `QO       Check each element for membership
          P     All sets must match
            н   Take the first result

1

Husk , 5 byte

►oLuΠ

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

Giải trình

Chỉ thấy điều phức tạp: Thông thường, đó là trường hợp với giải pháp của ngôn ngữ chơi gôn, chúng không hiệu quả lắm - cái này có độ phức tạp O (n · nⁿ).

►(Lu)Π  -- input as a list of lists, for example: [[1,2],[1,3],[1,4],[3,4]]
     Π  -- cartesian product: [[1,1,1,3],...,[2,3,4,4]]
►(  )   -- maximum by the following function (eg. on [1,1,1,3]):
   u    --   deduplicate: [1,3]
  L     --   length: 2

0

Pyth , 9 byte ((n n + 1 ))

Vì điều này hoạt động chính xác như giải pháp Jelly, rất có thể nó có độ phức tạp tương tự.

h{I#.nM*F

Hãy thử nó ở đây!

Làm sao?

h {I # .nM * F | Chương trình đầy đủ.

       * F | Gấp sản phẩm của Cartesian.
    .nM | Làm phẳng từng cái.
   # | Giữ những thứ đó:
 {I Đó là bất biến đối với việc loại bỏ các yếu tố trùng lặp.
h | Lấy yếu tố đầu tiên.

0

JavaScript (ES6), 74 73 byte

Đã lưu 1 byte, nhờ @Neil.

f=([a,...A],s=[],S)=>a?a.map(c=>s.includes(c)||(S=S||f(A,[...s,c])))&&S:s

Lặp lại đệ quy thông qua các mảng tìm kiếm một giải pháp.

Ung dung:

f=(
   [a, ...A],                        //a is the first array, A is the rest
   s = [],                           //s is the current trial solution
   S                                 //S holds the solution (if one exists) at this branch
  )=>
     a ? a.map(                      //if we're not done, iterate through a
           c => s.includes(c) ||     //  if this element already exists, short-circuit
                (S = S ||            //  else if S has a solution, keep it
                 f(A, [...s, c])     //  else look for a solution down this branch
                )
         ) && S                      //return S

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


Tại sao không a?a.map(... )&&S:s?
Neil

@Neil, vì Duh. Cảm ơn!
Rick Hitchcock

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.