Giới thiệu
Giả sử rằng bạn được trao một hoán vị ngẫu nhiên của n
các đối tượng. Hoán vị được niêm phong trong một hộp, vì vậy bạn không biết đó là n!
cái nào có thể. Nếu bạn quản lý để áp dụng hoán vị cho n
các đối tượng riêng biệt, bạn có thể suy ra ngay lập tức danh tính của nó. Tuy nhiên, bạn chỉ được phép áp dụng hoán vị cho n
các vectơ nhị phân có độ dài, có nghĩa là bạn sẽ phải áp dụng nó nhiều lần để nhận ra nó. Rõ ràng, áp dụng nó cho các n
vectơ chỉ với một 1
công việc, nhưng nếu bạn thông minh, bạn có thể làm điều đó với log(n)
các ứng dụng. Mã cho phương thức đó sẽ dài hơn, mặc dù ...
Đây là một thử thách thử nghiệm trong đó điểm của bạn là sự kết hợp giữa độ dài mã và độ phức tạp truy vấn , nghĩa là số lượng cuộc gọi đến một thủ tục phụ trợ. Thông số kỹ thuật hơi dài, vì vậy hãy chịu đựng tôi.
Nhiệm vụ
Nhiệm vụ của bạn là viết một hàm được đặt tên (hoặc tương đương gần nhất) f
, lấy đầu vào là một số nguyên dương n
và hoán vị p
của các n
số nguyên đầu tiên , sử dụng lập chỉ mục dựa trên 0 hoặc dựa trên 1. Đầu ra của nó là hoán vị p
. Tuy nhiên, bạn không được phép truy cập hoán vị p
trực tiếp . Điều duy nhất bạn có thể làm với nó là áp dụng nó cho bất kỳ vectơ n
bit nào. Với mục đích này, bạn sẽ sử dụng một hàm phụ trợ P
có hoán vị p
và vectơ bit v
và trả về vectơ hoán vị có p[i]
tọa độ th chứa bit v[i]
. Ví dụ:
P([1,2,3,4,0], [1,1,0,0,0]) == [0,1,1,0,0]
Bạn có thể thay thế "bit" với bất kỳ hai giá trị khác biệt, chẳng hạn như 3
và -4
, hoặc 'a'
và 'b'
, và họ không cần phải được cố định, vì vậy bạn có thể gọi P
với cả hai [-4,3,3,-4]
và [2,2,2,1]
trong cuộc gọi cùng f
. Định nghĩa của P
không được tính vào điểm số của bạn.
Chấm điểm
Độ phức tạp truy vấn của giải pháp của bạn trên một đầu vào đã cho là số lượng cuộc gọi mà nó thực hiện cho chức năng phụ trợ P
. Để làm cho biện pháp này rõ ràng, giải pháp của bạn phải có tính quyết định. Bạn có thể sử dụng các số giả ngẫu nhiên được tạo, nhưng sau đó bạn cũng phải sửa một hạt giống ban đầu cho trình tạo.
Trong kho lưu trữ này, bạn sẽ tìm thấy một tệp có tên là permutations.txt
50 hoán vị, 5 mỗi chiều dài từ 50 đến 150, bao gồm sử dụng lập chỉ mục dựa trên 0 (tăng mỗi số trong trường hợp dựa trên 1). Mỗi hoán vị nằm trên một dòng riêng và các số của nó được phân tách bằng dấu cách. Điểm của bạn là số byte của f
+ độ phức tạp truy vấn trung bình trên các đầu vào này . Điểm số thấp nhất chiến thắng.
Quy tắc bổ sung
Mã với giải thích được ưa thích, và sơ hở tiêu chuẩn không được phép. Cụ thể, các bit riêng lẻ không thể phân biệt được (vì vậy bạn không thể đưa ra một vectơ Integer
đối tượng P
và so sánh danh tính của chúng) và hàm P
luôn trả về một vectơ mới thay vì sắp xếp lại đầu vào của nó. Bạn có thể tự do thay đổi tên của f
và P
, và thứ tự mà họ lấy lý lẽ của họ.
Nếu bạn là người đầu tiên trả lời bằng ngôn ngữ lập trình của mình, bạn được khuyến khích đưa vào khai thác kiểm tra, bao gồm cả việc thực hiện chức năng P
cũng đếm số lần nó được gọi. Ví dụ, đây là khai thác cho Python 3.
def f(n,p):
pass # Your submission goes here
num_calls = 0
def P(permutation, bit_vector):
global num_calls
num_calls += 1
permuted_vector = [0]*len(bit_vector)
for i in range(len(bit_vector)):
permuted_vector[permutation[i]] = bit_vector[i]
return permuted_vector
num_lines = 0
file_stream = open("permutations.txt")
for line in file_stream:
num_lines += 1
perm = [int(n) for n in line.split()]
guess = f(len(perm), perm)
if guess != perm:
print("Wrong output\n %s\n given for input\n %s"%(str(guess), str(perm)))
break
else:
print("Done. Average query complexity: %g"%(num_calls/num_lines,))
file_stream.close()
Trong một số ngôn ngữ, không thể viết một khai thác như vậy. Đáng chú ý nhất, Haskell không cho phép hàm thuần P
ghi lại số lần nó được gọi. Vì lý do này, bạn được phép thực hiện lại giải pháp của mình theo cách nó cũng tính toán độ phức tạp truy vấn của nó và sử dụng giải pháp đó trong khai thác.
abaaabababaa
và-4 3 3 3 -4 3
sẽ là một vectơ của bit.