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/3
Prädikat. Das findall/3
Prädikat findet alle möglichen Werte für das erste Argument ( X
in 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 X
als Liste im letzten Argument ( [_|Z]
).
Der Ausdruck, der findall/3
als zweites Arugment übergeben wird, (append(X,Y,A),append(Y,X,A))
verwendet das append/3
Prädikat, um anzugeben, dass X
verkettet mit einigen noch nicht definierten Eingaben Y
gleich A
der Eingabezeichenfolge sein muss und dass dasselbe Y
verkettet mit gleich sein X
muss A
. Dies bedeutet, dass X
es sich um ein Präfix handeln muss, sodass die resultierende Zeichenfolge dieselbe ist A
wie, wenn sie von vorne entfernt A
und hinten hinzugefügt wird A
. Die Menge von X
s 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 A
auch Präfixe von sindA
das entspricht der 0-Drehung von A
. Da die 0
Drehung von .A
ist immer symmetrisch Die Länge der resultierenden Liste von X
s aus findall/3
ist 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/3
Prä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 Z
eins weniger ist als die Anzahl der vom findall/3
Prädikat gefundenen Präfixe und somit gleich der Anzahl der symmetrischen Umdrehungen von A
. Schließlich benutze ich das length/2
Prädikat, um B
die Länge von festzulegen Z
.