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
연결된 것과 동일한 X
것은 같아야 함을 지정 A
합니다. 이것은 X
접두사가 A
앞에 와서 제거되고 A
뒤에 추가되는 경우 결과 문자열이와 같아야 한다는 접두사 여야합니다 A
. X
이 속성을 가진 의 세트는 의 회전에 대칭 회전과 거의 일대일 대응 관계를 갖습니다A
. 빈 문자열과 A
접두사 라는 사실로 인해 이중 계산의 경우는 항상 정확히 하나 입니다.A
의 0 회전에 해당합니다 A
. 이후 0
의 회전이 A
의 결과 목록의 대칭 길이 항상 X
들에서 findall/3
의 대칭 회전 수에 1을 더한 것입니다 A
.
이중 계산 문제를 해결하기 위해 findall/3
조건 자의 세 번째 인수에 패턴 일치를 사용합니다 . 프롤로그에서 목록은 머리 (첫 번째 요소)와 꼬리 (나머지)의 쌍으로 표시됩니다. 따라서 [_|Z]
꼬리가 같은 목록을 나타냅니다 Z
. 이는 길이 Z
가 findall/3
술어 에서 찾은 접두사 수보다 1이 작으므로 대칭 회전 수와 같습니다 A
. 마지막으로 length/2
조건자를 사용 B
하여 길이 를 설정 합니다 Z
.