A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Probieren Sie es online aus!
Definiert ein Prädikat +/2, dessen erstes Argument eine Zeichenfolge (in Form einer Liste von Zeichencodes) ist (A ) verwendet und sein zweites Argument ( B) auf die Reihenfolge der symmetrischen Drehung höchster Ordnung setzt.
Erläuterung
Dieses Programm verwendet die Tatsache, dass die Menge der symmetrischen Rotationen auf einer Zeichenfolge eine zyklische Gruppe ist und daher die Reihenfolge der Menge der symmetrischen Rotationen gleich der Reihenfolge der symmetrischen Rotation höchster Ordnung ist. Somit kann das Programm das gewünschte Ergebnis berechnen, indem es die Gesamtzahl der symmetrischen Umdrehungen auf der Eingabezeichenfolge ermittelt.
Code Erklärung
Der Großteil des schweren Hebens erfolgt durch einen Anruf beim findall/3Prädikat. Das findall/3Prädikat findet alle möglichen Werte für das erste Argument ( Xin diesem Fall) so, dass der als zweites Argument angegebene Ausdruck wahr ist (dazu (append(X,Y,A),append(Y,X,A))später mehr). Schließlich speichert es jeden dieser möglichen Werte Xals Liste im letzten Argument ( [_|Z]).
Der Ausdruck, der findall/3als zweites Arugment übergeben wird, (append(X,Y,A),append(Y,X,A))verwendet das append/3Prädikat, um anzugeben, dass Xverkettet mit einigen noch nicht definierten Eingaben Ygleich Ader Eingabezeichenfolge sein muss und dass dasselbe Yverkettet mit gleich sein Xmuss A. Dies bedeutet, dass Xes sich um ein Präfix handeln muss, sodass die resultierende Zeichenfolge dieselbe ist Awie, wenn sie von vorne entfernt Aund hinten hinzugefügt wird A. Die Menge von Xs mit dieser Eigenschaft hat fast eine Eins-zu-Eins-Entsprechung mit den symmetrischen Rotationen von A. Es gibt immer genau einen Fall der Doppelzählung, der durch die Tatsache verursacht wird, dass sowohl die leere Zeichenfolge als Aauch Präfixe von sindAdas entspricht der 0-Drehung von A. Da die 0Drehung von .Aist immer symmetrisch Die Länge der resultierenden Liste von Xs aus findall/3ist eins größer als die Anzahl der symmetrischen UmdrehungenA
Um das Problem der Doppelzählung zu lösen, verwende ich den Mustervergleich für das dritte Argument des findall/3Prädikats. In Prolog werden Listen als Paare ihres Kopfes (das erste Element) und ihres Schwanzes (der Rest) dargestellt. Somit [_|Z]stellt eine Liste, deren Schwanz gleich ist, gleich ist Z. Dies bedeutet, dass die Länge von Zeins weniger ist als die Anzahl der vom findall/3Prädikat gefundenen Präfixe und somit gleich der Anzahl der symmetrischen Umdrehungen von A. Schließlich benutze ich das length/2Prädikat, um Bdie Länge von festzulegen Z.