我想在代码中看到比较2个值X和C1,如果两个值相等则X是C的反转值然后它应该打印比较值请告诉我如何执行此操作。它是打印Palindrome数字,如... 1,11,22,33,44,55,66,77,88,99,101 ....
go(N):-
write(0),nl,
go(0,N).
go(_,0):- !.
go(A,C):-
A1 is A,
C1 is A1 + 1,
/* write(C1),nl,*/
rev(C1,X),
/* write(X),nl,*/
/* To compare the Value of X and C1 and print if compared value is true*/
NewC is C-1,
go(C1,NewC).
rev(Q,E):-
name(Q, Q1),
reverse(Q1,E1),
name(E,E1).
答案 0 :(得分:2)
描述回文数对于CLP(FD)和DCG来说实际上是一项很好的任务。首先让我们描述一个回文数字的数字:
:- use_module(library(clpfd)).
palindromedigits(Digits) :- % Digits are palindrome digits if
Digits ins 0..9, % they are between 0 and 9
Digits = [H|_], % and the first digit...
H #\= 0, % ... is different from 0
phrase(palindrome, Digits). % and they form a palindrome
palindrome --> % a palindrome is
[]. % an empty list
palindrome --> % or
[_]. % a list with a single element
palindrome --> % or
[A], % an element A
palindrome, % followed by a palindrome
[A]. % followed by an element A
要测试一个数字是否为回文数,您可以将其转换为数字列表,palindromedigits/1
必须为该列表保留。要生成此类数字,您可以使用length/2
来描述所有可能长度的列表,palindromedigits/1
必须再次为这些列表保留,并且数字必须乘以它们各自的10的幂并总结。由于palindromedigits/1
排除了前导零,因此如果要将其包含在回文数中,则必须为0
添加一个事实。这可能看起来像这样:
palindromenumber(0). % 0 is a palindromenumber
palindromenumber(PN) :- % rule for testing numbers
number(PN), % succeeds if PN is a number
number_codes(PN,C), % C is a list of codes corresponding to the digits
maplist(plus(48),Digits,C), % codes and digits are off by 48
palindromedigits(Digits). % Digits is a palindrome
palindromenumber(PN) :- % rule for generating numbers
var(PN), % succeeds if PN is a variable
length(Digits,_), % Digits is a list of length 0,1,2,...
palindromedigits(Digits), % Digits is a palindrome
digits_number_(Digits,PN,1,0), % Digits correspond to the number PN
label(Digits). % labels the list Digits with actual numbers
请注意,与数字对应的代码关闭了48,因此maplist/3
的目标是关闭的,例如:
?- number_codes(123,C), maplist(plus(48),Digits,C).
C = [49, 50, 51], % <- the codes
Digits = [1, 2, 3]. % <- the actual digits
谓词digits_number_/4
非常简单。它被调用1
作为10的初始幂,0
作为数字的初始累加器。数字乘以对应于它们在数字中的位置的10的幂,然后加到累加器中。如果数字列表为空,则累加器保存与数字列表对应的数字。
digits_number_([],PN,_,PN).
digits_number_([D|Ds],PN,P,Acc) :-
Acc1 #= Acc + D*B,
P10 #= P*10,
digits_number_(Ds,PN,P10,Acc1).
请注意,数字与相反顺序的功率相乘并不重要,因为它是回文数。
现在您可以查询回文数:
?- palindromenumber(PN).
PN = 0 ;
PN = 1 ;
PN = 2 ;
.
.
.
PN = 33 ;
PN = 44 ;
PN = 55 ;
.
.
.
PN = 666 ;
PN = 676 ;
PN = 686 ;
.
.
.
PN = 7667 ;
PN = 7777 ;
PN = 7887
.
.
.
或者你可以测试一个数字是否是回文:
?- palindromenumber(121).
true ;
false.
?- palindromenumber(123).
false.
?- palindromenumber(12321).
true ;
false.
修改强>
要解决评论中的问题,您可以通过描述此序列与其长度之间的关系来实现。因此,您将拥有一个带有arity而不是arity的谓词。让我们给它一个很好的描述性名称,比如firstN_palindromicnumbers/2
。实际的realation由一个带有附加参数的谓词描述,该附加参数保存当前要检查的候选项。由于你想用1开始序列,这将是参数firstN_palindromicnumbers_ / 3将被调用:
firstN_palindromicnumbers(N,PNs) :-
firstN_palindromicnumbers_(N,PNs,1). % sequence starts with 1
通过递归,持有候选者的参数将增加1,而第一个参数N
将在每次候选结果变为实际回文数时减少。因此,谓词最终以N
为0
,空列表和我们不关心的候选者结束。这将是基本情况。否则,列表的头部是(序列的其余部分)中的最小回文数。您可以重复使用上面的目标number_codes/2
和maplist/3
来描述与当前候选人和DCG palindrome//0
对应的数字列表,以声明数字必须是回文。谓词palindromedigits/1
中的其他目标将不再需要,因为候选者将是1,2,3,...,因此由0到9的(至少一个)数字组成而没有前导零。你可以在Prolog中表达这样:
firstN_palindromicnumbers_(0,[],_C). % base case
firstN_palindromicnumbers_(N1,[C0|PNs],C0) :- % case: C0 is a palindrome
N1 #> 0, % sequence is not of desired length yet
number_codes(C0,Codes),
maplist(plus(48),Digits,Codes),
phrase(palindrome, Digits), % digits form a palindrome
N0 #= N1-1, % sequence of length N1-1 has to be described yet
C1 #= C0+1, % C1 is the next candidate
firstN_palindromicnumbers_(N0,PNs,C1). % PNs is the rest of the sequence
firstN_palindromicnumbers_(N1,PNs,C0) :- % case: C0 ain't a palindrome
N1 #> 0, % sequence is not of desired length yet
number_codes(C0,Codes),
maplist(plus(48),Digits,Codes),
\+ phrase(palindrome, Digits), % digits don't form a palindrome
C1 #= C0+1, % C1 is the next candidate
firstN_palindromicnumbers_(N1,PNs,C1). % PNs is the rest of the sequence
现在您可以查询谓词中给定长度的回文数字序列(请注意,使用SWI-Prolog,您可能需要点击 w 才能看到整个列表):
?- firstN_palindromicnumbers(15,PNs).
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] [write] % <- hit the w key
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66] ;
false.
?- firstN_palindromicnumbers(25,PNs).
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161] ;
false.
您还可以使用谓词来检查给定列表是否是第一个N
回文数字的序列:
?- firstN_palindromicnumbers(N,[1,2,3,4,5]).
N = 5 ;
false.
?- firstN_palindromicnumbers(N,[0|_]).
false.
?- firstN_palindromicnumbers(N,[1,2,3,4,11]).
false.
最常见的查询也会产生预期的答案:
?- firstN_palindromicnumbers(N,PNs).
N = 0,
PNs = [] ;
N = 1,
PNs = [1] ;
N = 2,
PNs = [1, 2] ;
N = 3,
PNs = [1, 2, 3] ;
.
.
.