2016-10-11 62 views
2

你好,我有一個問題,我執行的河內塔。 我需要用必要的移動打印列表清單,但是我的算法在光盤數N = 1時正常工作。 這是我的代碼河內之門prolog

move(1,X,Y,_,L) :- 
    append([X],[Y],L). 
move(N,X,Y,Z) :- 
    N>1, 
    M is N-1, 
    move(M,X,Z,Y), 
    move(1,X,Y,_), 
    move(M,Z,Y,X). 

這是結果,當N = 1

?- move(1,left,right,_,L). 

L = [left,right] 

(16 ms) yes 

我需要像這樣

L = [[left,center],[left,right],[center,right],[left,center],[right,left], 
     [right,center],[left,center],[left,right],[center,right],[center,left], 
[right,left],[center,right],[left,center],[left,right],[center,right]] 

當N = 4

請如果有人可以幫助我,我會成爲你的朋友。

+1

如果這是你的代碼完全按照你已經在這裏表示,注意到move'的'第一條具有5個參數,而第二個子句只有4個參數。我幾乎可以肯定這是一個錯誤。 – 2016-10-11 08:47:35

回答

0

有了一些小的變化,你可以寫:

move(1,X,Y,_,[[X,Y]]). 

move(N,X,Y,Z,L) :- 
    N>1, 
    M is N-1, 
    move(M,X,Z,Y,L1), 
    move(1,X,Y,_,L2), 
    move(M,Z,Y,X,L3), 
    append(L1,L2,L4), 
    append(L4,L3,L). 

例子:

?- move(4,left,right,center,L). 
L = [[left, center], [left, right], [center, right], [left, center], [right, left], [right, center], [left, center], [left, right], [center, right], [center, left], [right, left], [center, right], [left, center], [left, right], [center, right]] ; 
false. 
+0

謝謝!!我整夜都在處理! –

+0

很高興幫助! – coder

2

當描述名單 Prolog中,始終考慮使用符號!

例如,請考慮:

 
moves(1, X, Y, _) --> [X-Y]. 
moves(N, X, Y, Z) --> 
    { N #> 1, 
     M #= N-1 }, 
    moves(M, X, Z, Y), 
    moves(1, X, Y, _), 
    moves(M, Z, Y, X). 

注意,這...

  • 使用較少參數
  • 避免使用append/3

我還採取使用自由...

  • 名稱moves//4明確指出,我們所描述移動,而不是一個單一的移動
  • CLP(FD),用於聲明性算術約束(更容易理解)
  • (-)/2用於表示,如在序言的慣例。

樣品查詢,使用DCG中的phrase/2接口斷言:

 
?- phrase(moves(4,left,right,center), Ls). 
Ls = [left-center, left-right, center-right, left-center, right-left, ... ]. 
+0

真棒回答,請注意,結果是列表的清單,而不是列表,但它是更清晰的這種方式.... – coder

+2

謝謝你的鼓勵!是的,我冒昧地使用配對。要使用列表列表,只需要改變第一條規則,用'[X,Y]'替換'XY',但是''。'(X,'。'(Y,[])) '因此與' - (X,Y)'相比有些浪費。 – mat