Prolog Restrictions -> Solving Puzzle Grid

89 views
Skip to first unread message

PF

unread,
Dec 11, 2014, 6:55:50 PM12/11/14
to swi-p...@googlegroups.com

So guys, I'm learning restrictions with prolog, and trying to implement a little puzzle using this new knowledge.

The goal of the puzzle is simple: I have a square grid with some numbers on top/below each column and on the right/left of each row. The domain of values goes from 0 to Gridsize -1, wich means, a grid 7x7 can have numbers from 0 to 6. The restrictions are as follow:

  • Each number can only apear once each row and once each column
  • The number on top/right are the sum of the First and Last digits on the column/row respectively
  • The number on bottom/left are the sum of the Second and SecondLast digits on the column/row respectively
  • Zeros don't count as digits, are only on the program to represent blank spaces

For an example:


TopRestriction     = [7, 6, 4, 7, 3]
RightRestriction   = [5, 5, 5, 5, 5]
Bottom Restriction = [3, 4, 6, 3, 7]
LeftRestriction    = [5, 5, 5, 5, 5]


This restrictions can have a 0 too, wich make the program simple ignore (the sum can be any number, if it goes accordingly with the other restrictions).

One solution to the above lists would be the matrix:

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


Now the problem is: my restrictions somehow aren't applying, and the program isn't giving me the solution.

After puting the right domain and putting all column/row cells different(wich without any other restrictions it gives me the expected solution), I have this code to apply to each cell, the sum restrictions:

put_restrictions(Sol, Gridsize, SumT, SumR, SumB, SumL):-
                            put_restrictions_row
(Sol, Gridsize, SumR, SumL, 1),
                            put_restrictions_col
(Sol, Gridsize, SumT, SumB, 1).


Where Gridsize is the Gridsize to make iterations upon it, SumT, SumR, SumB, SumL, are the above restriction lists respectively, and 1 to start the iteration counter.

So this predicates are where my problem resides:

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


I think the code is pretty self explanatory, if not, what I'm trying to do:

If there is a restriction on right:

  • If the 1st and last cells of the row aren't 0, then their sum is = to the restriction
  • If the 1st cell on the row is 0, then the sum of 2nd cell of the row and the last = to the restriction -> makes the left restriction being the sum of the 3rd cell from the left and the secondlast And so on...

I'm not getting any solution on the problem. What am I doing wrong associating the restrictions?

Any help is welcome. Thanks in advance for helping the prologNoob here :P

Kilian Evang

unread,
Dec 13, 2014, 4:08:25 AM12/13/14
to swi-p...@googlegroups.com
Hi PF,

On 12/12/14 00:55, PF wrote:
> I'm not getting any solution on the problem. What am I doing wrong
> associating the restrictions?

I think the first step to find out would be to create an SSCCE:
http://sscce.org/

Cheers,
Kilian

Reply all
Reply to author
Forward
0 new messages