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, สายป้อนและที่เดียวYconcatenated ด้วยยังจะต้องเท่ากับX Aซึ่งหมายความว่าXจะต้องมีคำนำหน้าของบางอย่างAเช่นว่าถ้ามันถูกลบออกจากหน้าและเพิ่มไปยังด้านหลังแล้วสตริงส่งผลให้เป็นเช่นเดียวกับA AชุดของXs พร้อมด้วยคุณสมบัตินี้เกือบจะAมีการติดต่อแบบหนึ่งต่อหนึ่งกับการหมุนสมมาตร มีเสมอหนึ่งกรณีของการนับสองครั้งซึ่งเกิดจากความจริงที่ว่าทั้งสตริงที่ว่างเปล่าและAเป็นคำนำหน้าของAที่สอดคล้องกับ 0 Aการหมุนของ ตั้งแต่0-rotation ของAอยู่เสมอสมมาตรความยาวของรายการผลลัพธ์ของXs จากจะเป็นหนึ่งมากกว่าจำนวนผลัดสมมาตรบนfindall/3A
เพื่อแก้ปัญหาการนับซ้ำฉันใช้การจับคู่รูปแบบกับอาร์กิวเมนต์ที่สามของเพfindall/3รดิเคต ในรายการ Prolog จะแสดงเป็นคู่ของหัวของพวกเขา (องค์ประกอบแรก) และหางของพวกเขา (ส่วนที่เหลือ) จึงหมายถึงรายการที่มีหางเท่ากับเท่ากับ[_|Z] Zซึ่งหมายความว่าความยาวของZเป็นหนึ่งในน้อยกว่าจำนวนของคำนำหน้าพบโดยกริยาจึงเท่ากับจำนวนของการหมุนสมมาตรของfindall/3 Aสุดท้ายผมใช้length/2คำกริยาชุดความยาวของBZ