Prolog 序言中的自恋数

Prolog 序言中的自恋数,prolog,Prolog,大家好,我又来了,这周我做了以下作业: 我应该找到10和10000之间的所有数字,其属性如下例所示: 89 = 8^1 + 9^2 2427 = 2^1 + 4^2 + 2^3 + 7^4 = 2 + 16 + 8 + 2401 我在Haskell中实现了这一点,它工作得很好(我认为),并返回如下列表: [89,135,175,518,598,1306,1676,2427] ?- allNarc(X). X = 1*1000+3*100+0*10+6 ; X = 1*1000+6*100+7

大家好,我又来了,这周我做了以下作业:

我应该找到
10
10000
之间的所有数字,其属性如下例所示:

89 = 8^1 + 9^2
2427 = 2^1 + 4^2 + 2^3 + 7^4 = 2 + 16 + 8 + 2401
我在Haskell中实现了这一点,它工作得很好(我认为),并返回如下列表:

[89,135,175,518,598,1306,1676,2427]
?- allNarc(X).
X = 1*1000+3*100+0*10+6 ;
X = 1*1000+6*100+7*10+6 ;
X = 2*1000+4*100+2*10+7 ;
X = 0*100+4*10+3 ;    <- 43
X = 0*100+6*10+3 ;    <- 63
X = 1*100+3*10+5 ;
X = 1*100+7*10+5 ;
X = 5*100+1*10+8 ;
X = 5*100+9*10+8 ;
X = 8*10+9 ;
false.
然后我试着用Prolog(也按要求)编写它,如下所示:

num(0).
num(1).
num(2).
num(3).
num(4).
num(5).
num(6).
num(7).
num(8).
num(9).

allNarc(X):- num(A),num(B),num(C),num(D),
             X = A*1000+B*100+C*10+D,Y = A**1+B**2+C**3+D**4,
             X =:= Y,X>10.
allNarc(X):- num(B),num(C),num(D),
             X = B*100+C*10+D,Y = B**1+C**2+D**3,
             X =:= Y,X>10.
allNarc(X):- num(C),num(D),
             X = C*10+D,Y = C**1+D**2,
             X =:= Y,X>10.
结果是这样的:

[89,135,175,518,598,1306,1676,2427]
?- allNarc(X).
X = 1*1000+3*100+0*10+6 ;
X = 1*1000+6*100+7*10+6 ;
X = 2*1000+4*100+2*10+7 ;
X = 0*100+4*10+3 ;    <- 43
X = 0*100+6*10+3 ;    <- 63
X = 1*100+3*10+5 ;
X = 1*100+7*10+5 ;
X = 5*100+1*10+8 ;
X = 5*100+9*10+8 ;
X = 8*10+9 ;
false.
?-allNarc(X)。
X=1*1000+3*100+0*10+6;
X=1*1000+6*100+7*10+6;
X=2*1000+4*100+2*10+7;
X=0*100+4*10+3 两点

  • 当你说
    X=
    时,你是在统一
    =
    的左右两边。如果希望X是一个等于表达式求值的数字,请使用
    X is
  • 您希望防止在第一个位置出现零:
    num(a),a\=0,num(B),…
  • 做出这些更改后,我得到:

    ?- allNarc(X).
    X = 1306 ? ;
    X = 1676 ? ;
    X = 2427 ? ;
    X = 135 ? ;
    X = 175 ? ;
    X = 518 ? ;
    X = 598 ? ;
    X = 89 ? ;
    no
    
    您还可以使用
    bagof
    收集值。e、 g.
    bagof(X,allNarc(X),Narcs)。
    Narcs
    是您的值列表。

    您需要:

  • 防止第一个数字为0
  • 确保将X计算为所需的值。目前,您正在使用不合适的术语统一,您需要使用
    is
    关键字
  • 见:

    请注意,然后可以使用
    setof
    查找所有数字:

    ?- setof(X,allNarc(X),XL).
    XL = [89, 135, 175, 518, 598, 1306, 1676, 2427].
    

    这比一个接一个地列出要方便得多。

    嘿,非常感谢,我刚刚自己弄明白了。我更喜欢使用
    setof
    像我的haskell程序一样获得准确的列表。嘿,谢谢:)我发现我应该防止
    43=0^1+4^2+3^3
    之类的事情出现在我的结果中,这导致了你的解释
    1。
    顺便说一句,我更喜欢使用
    setof
    B)修复!我已经有一段时间没有做任何序言了,所以我忘记了
    setof
    :)。