A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
ลองออนไลน์!
กำหนดเพรดิเคต+/2
ที่รับสตริง (ในรูปแบบของรายการของรหัสอักขระ) เป็นอาร์กิวเมนต์แรก ( A
) และตั้งค่าอาร์กิวเมนต์ที่สอง ( B
) เป็นลำดับของการหมุนสมมาตรลำดับสูงสุด
คำอธิบาย
โปรแกรมนี้ใช้ข้อเท็จจริงที่ว่าชุดของการหมุนสมมาตรบนสตริงเป็นกลุ่มวงจรและลำดับของชุดการหมุนสมมาตรจะเท่ากับลำดับของการหมุนสมมาตรตามลำดับสูงสุด ดังนั้นโปรแกรมสามารถคำนวณผลลัพธ์ที่ต้องการโดยค้นหาจำนวนการหมุนแบบสมมาตรทั้งหมดบนสตริงอินพุต
รหัสคำอธิบาย
ส่วนใหญ่ของการยกของหนักจะกระทำโดยการเรียกไปที่ภาคfindall/3
แสดง เพรดิเคตfindall/3
ค้นหาค่าต่าง ๆ ที่เป็นไปได้ทั้งหมดสำหรับอาร์กิวเมนต์แรก ( X
ในกรณีนี้) เพื่อให้นิพจน์ที่กำหนดเป็นอาร์กิวเมนต์ที่สองเป็นจริง ( (append(X,Y,A),append(Y,X,A))
เพิ่มเติมในภายหลัง) ในที่สุดก็เก็บค่าแต่ละค่าที่เป็นไปได้เหล่านี้X
เป็นรายการในอาร์กิวเมนต์สุดท้าย ( [_|Z]
)
แสดงออกผ่านเข้ามาfindall/3
เป็น arugment ที่สอง(append(X,Y,A),append(Y,X,A))
ใช้append/3
คำกริยาเพื่อระบุว่าX
ตัดแบ่งกับบางส่วนยังไม่ได้กำหนดY
ต้องเท่ากับA
, สายป้อนและที่เดียวY
concatenated ด้วยยังจะต้องเท่ากับX
A
ซึ่งหมายความว่าX
จะต้องมีคำนำหน้าของบางอย่างA
เช่นว่าถ้ามันถูกลบออกจากหน้าและเพิ่มไปยังด้านหลังแล้วสตริงส่งผลให้เป็นเช่นเดียวกับA
A
ชุดของX
s พร้อมด้วยคุณสมบัตินี้เกือบจะA
มีการติดต่อแบบหนึ่งต่อหนึ่งกับการหมุนสมมาตร มีเสมอหนึ่งกรณีของการนับสองครั้งซึ่งเกิดจากความจริงที่ว่าทั้งสตริงที่ว่างเปล่าและA
เป็นคำนำหน้าของA
ที่สอดคล้องกับ 0 A
การหมุนของ ตั้งแต่0
-rotation ของA
อยู่เสมอสมมาตรความยาวของรายการผลลัพธ์ของX
s จากจะเป็นหนึ่งมากกว่าจำนวนผลัดสมมาตรบนfindall/3
A
เพื่อแก้ปัญหาการนับซ้ำฉันใช้การจับคู่รูปแบบกับอาร์กิวเมนต์ที่สามของเพfindall/3
รดิเคต ในรายการ Prolog จะแสดงเป็นคู่ของหัวของพวกเขา (องค์ประกอบแรก) และหางของพวกเขา (ส่วนที่เหลือ) จึงหมายถึงรายการที่มีหางเท่ากับเท่ากับ[_|Z]
Z
ซึ่งหมายความว่าความยาวของZ
เป็นหนึ่งในน้อยกว่าจำนวนของคำนำหน้าพบโดยกริยาจึงเท่ากับจำนวนของการหมุนสมมาตรของfindall/3
A
สุดท้ายผมใช้length/2
คำกริยาชุดความยาวของB
Z