0

皆さん、私はプロローグで制約を学び、この新しい知識を使って小さなパズルを実装しようとしています.

パズルの目的は単純です。各列の上/下、および各行の右/左にいくつかの数字がある正方形のグリッドがあります。値のドメインは 0 から Gridsize -1 になります。つまり、グリッド 7x7 は 0 から 6 までの数値を持つことができます。制約は次のとおりです。

  • 各数値は、各行に 1 回、各列に 1 回のみ表示されます
  • 上/右の数字は、それぞれ列/行の最初と最後の桁の合計です
  • 下/左の数字は、それぞれ列/行の 2 番目と 2 番目の最後の桁の合計です
  • ゼロは数字としてカウントされず、プログラム上で空白を表すためだけに使用されます

例:

TopConstraint = [7, 6, 4, 7, 3] RightConstraint = [5, 5, 5, 5, 5] BottomConstraint = [3, 4, 6, 3, 7] LeftConstraint = [5, 5, 5, 5, 5]

この制約には 0 を指定することもできます。これにより、プログラムは単純に無視されます (合計は、他の制約に従っていれば、任意の数にすることができます)。

上記のリストに対する 1 つの解決策は、次のマトリックスです。

3 | 4 | 1 | | 2 1 | 3 | 2 | 4 | 2 | | 4 | 1 | 3 | 1 | 3 | 2 | 4 4 | 2 | | 3 | 1

問題は、制約がどうにか適用されず、プログラムが解決策を提供していないことです。

正しいドメインを配置し、すべての列/行セルを異なるものに配置した後(他の制限なしで、期待される解決策が得られます)、各セルに適用するこのコードがあります。合計制限:

put_restrictions(Sol, Gridsize, SumT, SumR, SumB, SumL):- put_restrictions_row(Sol, Gridsize, SumR, SumL, 1), put_restrictions_col(Sol, Gridsize, SumT, SumB, 1). ここで、Gridsize は反復を行うための Gridsize であり、SumT、SumR、SumB、SumL はそれぞれ上記の制約リストであり、1 は反復カウンターを開始します。

したがって、この述語は私の問題がある場所です

put_restrictions_col(_, Gridsize, _, _, X):-  X > Gridsize, write('end put_restrictions_col'),nl.
put_restrictions_col(Grid, Gridsize, [SumTH|SumTT], [SumBH|SumBT], X):- 
                                get_cell(Grid, FirstInCol, X, 1, Gridsize),
                                get_cell(Grid, LastInCol, X, Gridsize, Gridsize),

                                get_cell(Grid, SecondInCol, X, 2, Gridsize),
                                SecondLastIndex is Gridsize-1,
                                get_cell(Grid, SecondLastInCol, X, SecondLastIndex, Gridsize),

                                get_cell(Grid, ThirdInCol, X, 3, Gridsize),
                                ThirdLastIndex is Gridsize-2,
                                get_cell(Grid, ThirdLastInCol, X, ThirdLastIndex, Gridsize),


                            (SumTH #> 0) #=> 
                            (
                                (((FirstInCol #> 0) #/\ (LastInCol #> 0)) #=> (SumTH #= FirstInCol + LastInCol))
                                #\/
                                ((FirstInCol #= 0) #=> (SumTH #= SecondInCol + LastInCol))
                                #\/
                                ((LastInCol #= 0) #=> (SumTH #= FirstInCol + SecondLastInCol))
                            ),

                            (SumBH #> 0) #=>
                            (
                                (((SecondInCol #> 0) #/\ (SecondLastInCol #> 0)) #=> (SumBH #= SecondInCol + SecondLastInCol))
                                #\/
                                ((SecondInCol #= 0) #=> (SumBH #= ThirdInCol + SecondLastInCol))
                                #\/
                                ((SecondLastInCol #= 0) #=> (SumBH #= SecondInCol + ThirdLastInCol))
                            ),


                                                    X1 is X+1,
                                                    put_restrictions_col(Grid, Gridsize, SumTT, SumBT, X1).

put_restrictions_row([], _, _,_,_):- write('end put_restrictions_row'),nl.
put_restrictions_row([H|T], Gridsize, [SumRH|SumRT],[SumLH|SumLT], N):-
                            element(1, H, FirstInRow),
                            element(Gridsize, H, LastInRow),

                            element(2, H, SecondInRow),
                            SecondLastIndex is Gridsize -1,
                            element(SecondLastIndex, H, SecondLastInRow),

                            element(3, H, ThirdInRow),
                            ThirdLastIndex is Gridsize -2,
                            element(ThirdLastIndex, H, ThirdLastInRow),

                            (SumRH #> 0) #=> 
                                (
                                (((FirstInRow #> 0) #/\ (LastInRow #> 0)) #/\ (FirstInRow + LastInRow #= SumRH))

                                #\/
                                ((FirstInRow #= 0) #/\ (SecondInRow + LastInRow #= SumRH))
                                #\/
                                ((LastInRow #= 0) #/\ (FirstInRow + SecondLastInRow #= SumRH))
                                ),

                            (SumLH #> 0) #=>
                                (
                                (((SecondInRow #> 0) #/\ (SecondLastInRow #> 0)) #/\ (SumLH #= SecondInRow + SecondLastInRow))
                                #\/
                                ((SecondInRow #= 0) #/\ (SumLH #= ThirdInRow + SecondLastInRow))
                                #\/
                                ((SecondLastInRow #= 0) #/\ (SumLH #= SecondInRow + ThirdLastInRow))
                                ),



                        N1 is N+1,
                        put_restrictions_row(T, Gridsize, SumRT, SumLT, N1).

コードはかなり自明だと思いますが、そうでない場合は、私がやろうとしていることは次のとおりです。

右側に制約がある場合:

  • 行の最初と最後のセルが 0 でない場合、それらの合計は = 制限に
  • 行の最初のセルが 0 の場合、行の 2 番目のセルと最後の = の合計が制限に -> 左の制限は、左から 3 番目のセルと最後から 2 番目のセルの合計になります。 .

問題の解決策が得られません。制約の関連付けで何が間違っていますか?

どんな助けでも大歓迎です。ここでprologNoobを助けてくれてありがとう:P

4

1 に答える 1