5

暗号算術パズルを解くための Prolog プログラムを作成する必要があります。

変数 [A, M, P, D, Y] を 0 から 9 の値に割り当てて、方程式 AM+PM を満たす関数 solve([A, M, P, D, Y]) を作成する必要があります。 =日。各変数には異なる値が割り当てられ、A、P、および D は 0 に等しくなりません。

この関数を書き始めましたが、プログラムの実行中に問題が発生しました。A、P、D がゼロにならないという制限を設定しました。アルゴリズムを調べているうちに、D は 1 でなければならないことに気がついたので、プログラムの最初にそれを定義しました。M に対して 2 つの異なる変数 (M1 と M2) を定義し、それらを互いに等しく設定しました。これは、パズル内の異なる M が同じ値に割り当てられる必要があるためです。さまざまな変数に場所を割り当て、パズルに基づいてそれらを合計しました。キャリーイン変数で運ばれる変数を考慮しました。プログラムはコンパイルされますが、関数が実行されません。

solve([A, M1, M2, P, D, Y]):- D is 1,
A/=0,
P/=0,
D/=0,
M1 = M2,
select(M1, [0,2,3,4,5,6,7,8,9], R1),
select(M2, R1, R2),
Y is (M1+M2) mod 10,
C1 is (M1+M2) // 10,
select(Y, R2, R3),
select(A, R3, R4),
select(P, R4, R5),
select(D, R5, R6),
A is (A+P+C1) mod 10,
D is (A+P+C1)// 10.

私は何を間違っていますか?変数の定義に何か問題がありますか? 2 つの異なる M 変数を定義する必要がありますか、それとも 1 つで十分ですか?

4

4 に答える 4

3

これがあなたのパズルの私の解決策です。私たちは単にPROLOGのバックトラックに依存しています。最初にすべての変数を選択してから、パズルの状態を確認します。2つのMを定義する必要はないと思います。

solve([A,M,P,D,Y]):- 
select(A,[0,1,2,3,4,5,6,7,8,9],WA), % W means Without
not(A=0),
select(M,WA,WMA),
select(P,WMA,WMAP),
not(P=0),
select(D,WMAP,WMAPD),
not(D=0),
select(Y,WMAPD,WMAPDY),
DAY is 100*D+10*A+Y,
AM  is 10*A+M,
PM  is 10*P+M,
DAY is AM+PM.
于 2012-12-14T00:59:29.563 に答える
1

あなたは次のように書いています:「私のプログラムはコンパイルされますが、関数は実行されません:」

solve([A, M1, M2, P, D, Y]):- D is 1,
    A/=0,

不思議ではありません。まず/=、Prolog には演算子がありません。という意味だったと思います\=。しかしA \= B、「A は B と統合できない」という意味です。あなたの場合Bは0ですAが、まだ設定されていない論理変数です。にでも統一できます。関連するすべての logvar がインスタンス化された、不等式\=チェックするためにのみ使用する必要があります。

だから、A \= 0 失敗します。(もう 1 つのことは、M1=M2不要です。全体で使用できますM)。

このようなパズルを解決するための一般的なツールは、狭いドメインからの一意の選択です。

selectM([A|As],S,Z):- select(A,S,S1),selectM(As,S1,Z).
selectM([],Z,Z).

それがあれば、あなたのパズルはただ

solve([A,M,P,D,Y]):-
  selectM([A,P,D],[1,2,3,4,5,6,7,8,9],R),     % R is the remaining domain
  selectM([M,Y],[0|R],_),                     % don't care what remains
  10*(A+P)+M+M =:= 100*D+10*A+Y.

可能であれば、検索する前に割り当てを見つけるという正しい考えがあります。あなたのアプローチを使用すると、次のように書くことができます

solve([A,M,P,D,Y]):-    
  selectM([M,A],[0,1,2,3,4,5,6,7,8,9],R),
  A =\= 0,
  Y  is (M+M) mod 10,     % AM+PM=DAY
  C1 is (M+M) // 10,
  A  is (A+P+C1) mod 10,
  D  is (A+P+C1) // 10,
  selectM([P,D,Y],R,_),   % ensure all are different
  p =\= 0, D =\= 0.

繰り返しますが、その値をテストする前に選択する必要があります。A

于 2012-12-16T11:04:55.603 に答える
0

あなたの問題はDへの複数の「割り当て」だと思います。最初のDは1にバインドされ、その後は値を変更できません(プロローグは割り当てではなく統一を使用します)。それから両方

...
select(D, R5, R6),
...
D is (A+P+C1)// 10.

D が 1 以外の場合は失敗します

于 2012-12-14T06:36:28.057 に答える