Нарциссический номер в прологе - PullRequest
2 голосов
/ 08 июня 2011

Привет всем, я снова здесь, на этой неделе я получил эту домашнюю работу:

Я должен найти все числа между 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]

, а затем я попытался написать его в прологе (по мере необходимости тоже)) вроде следующего:

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.

результат примерно такой:

?- 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.

явно 43 и 64 не должны принадлежать этой группе, а результат просто уродливМожет ли кто-нибудь помочь мне получить вывод, как результат в моей реализации Haskell?

Ответы [ 2 ]

3 голосов
/ 08 июня 2011

Два очка.

  1. когда вы говорите X =, вы объединяете левую и правую стороны =. Если вы хотите, чтобы X был числом, равным оценке выражения, используйте X is <expression here>.
  2. Вы хотите предотвратить ноль в первой позиции: 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 для сбора значений. например bagof(X,allNarc(X),Narcs). Narcs - это список ваших значений.

2 голосов
/ 08 июня 2011

Вам необходимо:

  1. Не допускать, чтобы первые цифры были равны 0.
  2. Убедитесь, что значение X соответствует желаемому значению.В настоящее время вы используете термин унификация, который не подходит, вам нужно использовать ключевое слово is.

См .:

num(0).
num(1).
num(2).
num(3).
num(4).
num(5).
num(6).
num(7).
num(8).
num(9).
posnum(A) :- num(A), A \= 0.

allNarc(X):- posnum(A),num(B),num(C),num(D),
             X is A*1000+B*100+C*10+D,Y is A**1+B**2+C**3+D**4,
             X =:= Y,X>10.
allNarc(X):- posnum(B),num(C),num(D),
             X is B*100+C*10+D,Y is B**1+C**2+D**3,
             X =:= Y,X>10.
allNarc(X):- posnum(C),num(D),
             X is C*10+D,Y is C**1+D**2,
             X =:= Y,X>10.

Обратите внимание, что вы можете найти всечисла, использующие setof:

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

Это гораздо удобнее, чем перечислять их один за другим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...