2016-04-14 11 views
0

私はPrologでリストを囲むようにしています。これを行うには、私は一種のゲームを作成しようとしています。繰り返すことができる1-9のリストを渡します。リストは任意の長さにすることができます。ルールは、最初の要素(e)から始まり、終了するまでe + 2またはe + 3に移動することしかできません。目標は最も高い数字に「着陸」することです。本質的には、ホップスコッチのようなものです。私が実行している問題は、パスのすべての可能な置換を決定することです。これまでのところ、私は以下を持っています。使用する指定された式を使用してリストの置換が可能です

paths([], []). %empty list returns empty list 
paths([X], [X]). %list with one element returns that one element 
paths([X1, X2], [X1]). %list with 2 elements returns the first element 
paths([X1, X2, X3], [X1,X3]). %list with three elements returns the first and third element 
paths() :- % the recursive case for a list with 4+ elements 

リストは次のようになります。[1,2,3,4,5,6,8,7,9,3,6,5,7,8,9] 私が言及したルールを使用して、すべての可能なパスを決定する必要があります。私は、リストはPrologでインデックスを作成することができ:(

どれロジックガイダンスは理解されることを望む

+0

私は、[この]を考える(http://stackoverflow.com/questions/36579234/prolog-generating-every-possibility -of-a-list-given-a-pattern)はあなたが探しているものです。 – tas

答えて

0

私はindexing回避するための理由があると思う:。。シンプルさがあなたの問題を分解する場合は、多分あなたは書き始めることができ私は非常によくあなたのゲームを理解していない、遊び場のいくつかの例:

step([_,X|T],X,T). 
step([_,_,X|T],X,T). 

、その後

paths([],[]). 
paths(L,[X|Xs]) :- step(L,X,T), paths(T,Xs). 

ノートのようなステップ/ 3述語解決策を歓迎します。

+1

この意味でのインデックス作成は非常に珍しいことです。 – false

1

要件が完全に明確ではないが、ようです:

  • 2番目の引数は 最初の引数は(あなたが最初の「広場に「ホップ」と同じ最初の要素が要求されています『上の土地 「あなたが最初のリストの最後の要素は、(あなたがそのあなたの第二のリストの 最後の要素を必要されていないことを必要とされていません

  • ) あなたの石蹴りのmetaphoreを使用して、常に最初に』最後の「正方形」)。

  • 空のリストは空のリスト結果で成功します(空のリストで失敗するのではなく、もう1つの有効な方法です)。

これは次のように実装できます。再帰節と単純な基底のケースで扱われるので、2項と3項の明示的なリストケースはあまり必要ありません。

path([], []). 
path([X], [X]). 
path([X,_|T], [X|R]) :- % hop over 1 element 
    path(T, R). 
path([X,_,_|T], [X|R]) :- % hop over 2 elements 
    path(T, R). 

簡単な例:私はあなたの要件を正確に権利がない場合は

| ?- path([1,2,3,4,5,6], R). 

R = [1,3,5] ? ; 

R = [1,3,6] ? ; 

R = [1,4,6] ? ; 

R = [1,4] 

yes 

、あなたはそれが再帰的なケースを処理する方法を示して、あなたのニーズに合わせて、これを調整することができるはずです。ホップの値を最適化しようとする方向に向かっているようにも聞こえますが、これもまた練習として残します。

これ

もDCG(確定節文法)で行うことができます行使されるだろう

path([]) --> []. 
path([X]) --> [X]. 
path([X|T]) --> ([X,_] | [X,_,_]), path(T). 

:最後のステップが取られ、余分な要件に照らして

| ?- phrase(path(R), [1,2,3,4,5,6]). 

R = [1,3,5] ? ; 

R = [1,3,6] ? ; 

R = [1,4,6] ? ; 

R = [1,4] ? ; 

(1 ms) no 
| ?- 


必要がありますリスト内にあるものであれば、 path/2述語の更新版があります。

path([], []). 
path([X], [X]). 
path([X,_], [X]). 
path([X,_,Y|T], [X|R]) :- % hop over 1 element 
    path([Y|T], R). 
path([X,_,_,Y|T], [X|R]) :- % hop over 2 elements 
    path([Y|T], R). 
だから、
+0

これは近いですが、私は解決策を思いついたと思います。あなたが私の答えが有用であると分かったら、 –

+0

@ ZackHerbertの下に投稿します。おそらくあなたはそれをアップヴォートすることができます。あなたの要件は完全にはっきりしていないので、私はあなたの正確なニーズを打つことを期待していませんでした。しかし、この答えは、どのように進めるかを理解する上で大いに役立つはずです。 – lurker

+0

助けてくれてありがとう –

0
%passing in a list and return all possible paths using K+2 or K+3 with K being the first element of the list. 
%empty list returns empty list 
%list with one element returns that one element 
%list with 2 elements returns the first element 
%list with three elements returns the first and third element 
%list with four/four+ elements needs to be called recursively, prefix them with the first element and append them together 
%RL means ReturnList 
%FL means FinalList 
%List is the appended list containing all the paths 
paths([], []). 
paths([X], [[X]]). 
paths([X1, X2], [[X1]]). 
paths([X1, X2, X3], [[X1,X3]]). 
paths([X1, X2, X3, X4 | T], List) :- 
    paths([X3,X4|T], RL), paths([X4|T], RL2), 
    prefix_all(X1, RL, FL1), prefix_all(X1, RL2, FL2), 
    append(FL1, FL2, List). 

リスト[1,2,3,4,5]で実行した場合、次を生成する次のとおりです。

| ?- paths([1,2,3,4,5],X). 

X = [[1,3,5],[1,4]] ? ; 
no 
+0

なぜ[[1,3] 'は最後の要素4と5をスキップする有効なパスではありませんか?また、 'findall/3':' findall(P、path([1,2,3,4,5]、P)、Paths) 'を使って、私の答えで完全なリスト結果を得ることができます。 'findall/3'を実行して、すべての解を収集するために、論理からのパスを定義する関係の論理を分離します。 – lurker

+0

@lurkerリストの最後に移動する必要があるためです。できるだけ毎回e + 2またはe + 3を移動する必要があります。ルールが最初に不明な場合は申し訳ありません。 –

+0

'[1,3]'は毎回e + 2またはe + 3を動かすだけです。 '[1,2,3,4,5]'のリストは、1で始まります。e + 2に行くと3になります。パスは '[1,3]'です。それから、e + 3を行って、ちょうど5を過ぎたところで行くのはなぜですか?[1,4]解決策とは何が違うのですか?なぜなら、1から始まり、e + 3で4になり、e + 5? – lurker

関連する問題