A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Hãy thử trực tuyến!
Xác định một vị từ +/2
lấy một chuỗi (dưới dạng danh sách mã ký tự) làm đối số thứ nhất ( A
) và đặt đối số thứ hai ( B
) của nó theo thứ tự xoay đối xứng bậc cao nhất.
Giải trình
Chương trình này sử dụng thực tế là tập hợp các phép quay đối xứng trên một chuỗi là một nhóm tuần hoàn và do đó thứ tự của tập hợp các phép quay đối xứng bằng với thứ tự của phép quay đối xứng bậc cao nhất. Do đó, chương trình có thể tính toán kết quả mong muốn bằng cách tìm tổng số phép quay đối xứng trên chuỗi đầu vào.
Giải thích mã
Phần lớn của việc nâng vật nặng được thực hiện bằng một cuộc gọi đến findall/3
vị ngữ. Vị findall/3
ngữ tìm thấy tất cả các giá trị khác nhau có thể có cho đối số thứ nhất ( X
trong trường hợp này) sao cho biểu thức được đưa ra làm đối số thứ hai là đúng ( (append(X,Y,A),append(Y,X,A))
, nhiều hơn về điều đó sau). Cuối cùng, nó lưu trữ từng giá trị có thể này X
dưới dạng một danh sách trong đối số cuối cùng ( [_|Z]
).
Biểu thức được truyền vào findall/3
dưới dạng arugment thứ hai, (append(X,Y,A),append(Y,X,A))
sử dụng biến append/3
vị ngữ để xác định rằng X
nối với một số chưa được xác định Y
phải bằng A
, chuỗi đầu vào và cùng được Y
nối với X
cũng phải bằng A
. Điều này có nghĩa là X
phải có một số tiền tố A
sao cho nếu nó được xóa khỏi mặt trước A
và thêm vào phía sau thì chuỗi kết quả giống như A
. Tập hợp X
s với tính chất này gần như có sự tương ứng một-một với các phép quay đối xứng của A
. Luôn luôn có chính xác một trường hợp đếm kép được gây ra bởi thực tế là cả chuỗi rỗng và A
tiền tố củaA
tương ứng với 0 vòng quay của A
. Vì sự 0
bảo vệ của A
luôn luôn đối xứng nên độ dài của danh sách kết quả của X
s findall/3
sẽ lớn hơn số lần quay đối xứng trên A
.
Để giải quyết vấn đề đếm kép, tôi sử dụng khớp mẫu trên đối số thứ ba của findall/3
vị ngữ. Trong danh sách Prolog được thể hiện dưới dạng cặp đầu (phần tử đầu tiên) và đuôi của chúng (phần còn lại). Do đó, [_|Z]
đại diện cho một danh sách có đuôi bằng với Z
. Điều này có nghĩa là độ dài của Z
một ít hơn số lượng tiền tố được tìm thấy bởi findall/3
vị ngữ và do đó bằng với số lần quay đối xứng của A
. Cuối cùng, tôi sử dụng length/2
vị ngữ để đặt thành B
độ dài của Z
.