Những danh sách này có bằng nhau không?


19

Như bạn có thể biết rất rõ python có danh sách. Như bạn có thể không biết những danh sách này có thể chứa chính họ.

a = []
a.append(a)

Con trăn 2

Con trăn 3

Đây là những điều thú vị và có rất nhiều điều thú vị bạn có thể làm với chúng, tuy nhiên bạn không thể so sánh chúng.

a = []
a.append(a)
b = []
b.append(b)
a == b

Con trăn 2

Con trăn 3

Bài tập

Công việc của bạn là viết một hàm bằng Python (hoặc bất kỳ ngôn ngữ nào có thể xử lý trực tiếp các đối tượng python) sẽ lấy hai danh sách có thể chứa chính chúng và so sánh chúng.

Hai danh sách bằng nhau nếu chúng có cùng độ dài và không tồn tại dãy số sao cho việc lập chỉ mục cả hai danh sách theo chuỗi đó dẫn đến hai đối tượng không bằng nhau theo định nghĩa này bằng nhau. Tất cả các đối tượng không có trong danh sách có trong danh sách sẽ là số nguyên python để đơn giản và nên được so sánh với đẳng thức dựng sẵn của python cho số nguyên.

Chương trình của bạn không nên dựa vào độ sâu đệ quy của python để xác định xem danh sách có sâu vô hạn hay không. Đó là:

def isInfinite(a,b):
 try:
  a==b
  return False
 except RunTimeError:
  return True

Không phải là một cách hợp lệ để xác định nếu hai danh sách là tự tham khảo.

Tủ thử

Giả sử bạn xác định hàm equal

a = []
a.append(a)
b = []
b.append(b)
print(equal(a,b))

True

a = []
b = []
a.append(b)
b.append(a)
print(equal(a,b))

True

a = []
b = []
a.append(1)
a.append(b)
b.append(1)
b.append(a)
print(equal(a,b))

True

a = []
a.append(a)
b = [a]
print(equal(a,b))

True

a = []
b = []
c = []
a.append(b)
b.append(c)
c.append(a)
equal(a,b)

True

a=[1,[2]]
b=[1,[2,[1]]]
a[1].append(a)
b[1][1].append(b[1])

True

a = []
a.append(a)
b = [1]
b.append(a)
c = [1]
c.append([c])
print(equal(b,c))

False

a = []
b = []
a.append(1)
a.append(b)
b.append(a)
b.append(1)
print(equal(a,b))

False

a = []
b = []
a.append(a)
b.append(b)
b.append(b)
print f(a,b)

False

17
Là một lưu ý phụ cho các cử tri tiềm năng: Lưu ý rằng các thách thức chung về ngôn ngữ thường được tán thành ngoại trừ trong một số trường hợp nhất định (như các nhiệm vụ chỉ thú vị trong một số ngôn ngữ nhất định). IMO, đây là một ví dụ tuyệt vời về một thách thức ngôn ngữ cụ thể.
DJMcMayhem

@WheatWizard Điều đó không đủ chính xác - các danh sách lồng nhau cũng cần phải có cùng độ dài.
xnor

@WheatWizard Bạn thực sự có thể so sánh chúng. Trong Python, bạn chỉ nhận được "vượt quá giới hạn đệ quy" nếu chúng không bằng nhau. tio.run/nexus/ từ
mbomb007

@ mbomb007 Đó là vì python mặc định so sánh các tài liệu tham khảo. Nếu bạn có hai đối tượng giống hệt nhau có các tham chiếu khác nhau thì sẽ thất bại, do đó thách thức.
Thuật sĩ lúa mì

2
Bạn có thể mở rộng thử thách này cho tất cả các ngôn ngữ nơi danh sách có thể chứa chính chúng không?
Máy

Câu trả lời:


9

Python 2 , 94 byte

g=lambda c,*p:lambda a,b:c in p or all(map(g((id(a),id(b)),c,*p),a,b))if a>[]<b else a==b
g(0)

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

Một cải tiến về giải pháp rất thông minh của isaacg là lưu trữ các idcặp danh sách đang được xử lý và khai báo chúng bằng nhau nếu so sánh tương tự xuất hiện ở cấp độ thấp hơn.

Bước đệ quy all(map(...,a,b))nói rằng abbằng nhau nếu tất cả các cặp phần tử tương ứng trong chúng đều bằng nhau. Điều này hoạt động độc đáo để từ chối chiều dài không bằng nhau vì mapđệm danh sách ngắn nhất với None, không giống như zipcắt ngắn. Vì không có danh sách thực tế nào chứa None, những danh sách đệm này sẽ luôn bị từ chối.


Mục đích của ,sau là cgì?
Thuật sĩ lúa mì

Nó làm cho nó một tuple.
mbomb007

a=[];a+=[a,1];b=[];b+=[b,2];f(a,b)tràn ngăn xếp, và a=[1];b=[2];f(a,b);f(a,b)trông giống như một vấn đề tái sử dụng.
Anders Kaseorg

@AndersKaseorg Tôi thấy, việc thay đổi danh sách đang yêu cầu sự cố. Tôi nghĩ rằng điều này sửa chữa nó.
xnor

1
@AndersKaseorg Và tôi thấy bạn đã viết về cơ bản cùng một giải pháp chức năng trong một chức năng. Có một giải pháp 95 byte mà không cần điều đó : f=lambda a,b,p=[0]:p[0]in p[1:]or all(map(f,a,b,[[(id(a),id(b))]+p]*len(a)))if a>[]<b else a==b. Có lẽ có một cách tốt hơn để xử lý map.
xnor

5

Python, 233 218 197 217 byte

d=id
def q(a,b,w):
 w[(d(a),d(b))]=0
 if d(a)==d(b):return 1
 if(a>[]and[]<b)-1:return a==b
 if len(a)!=len(b):return 0
 for x,y in zip(a,b):
  if((d(x),d(y))in w or q(x,y,w))-1:return 0
 return 1
lambda a,b:q(a,b,{})

Hàm ẩn danh trên dòng cuối cùng thực hiện chức năng mong muốn.

Điều này vẫn đang trong quá trình chơi golf, tôi chỉ muốn chứng tỏ rằng điều này là có thể.

Về cơ bản, chúng tôi đặt một mục trong w nếu chúng tôi đang làm việc trên một kiểm tra nhất định. Hai thứ bằng nhau nếu chúng là cùng một đối tượng, nếu chúng không phải là danh sách và chúng bằng nhau hoặc nếu tất cả các yếu tố của chúng đều bằng nhau hoặc đang được xử lý.


Bạn không thể sử dụng a>[]thay vì i(a,list)?
mbomb007

@ mbomb007 Điều này đã được viết trước khi quy tắc "Mọi thứ là danh sách hoặc số nguyên" được thêm vào. Sẽ nâng cấp.
isaacg

Bạn có thể sử dụng a>[]<blen(a)-len(b)
mbomb007

@ETHproductions Oh, số byte của anh ấy là sai. Đó là lý do
mbomb007

Có thể d(a)==d(b)được a is bkhông? Điều đó sẽ cắt giảm hai sử dụng d.
xnor
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.