Search code examples
prologmagic-square

prolog I have to make a program that calculates the magic matrix permutate


I have to make a program that calculates the magic matrix, I have made ​​my code and it works but my permute is very slow. I need one that is faster someone can help me Please

This is the code:

diabolico([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]) :- 
    permutar([1,14,3,16,5,12,13,15,9,10,11,6,7,2,8,4],[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]),
    A+B+C+D=:=34, E+F+G+H=:=34, I+J+K+L=:=34, M+N+O+P=:=34,
    A+E+I+M=:=34, B+F+J+N=:=34, C+G+K+O=:=34, D+H+L+P=:=34,
    M+B+G+L=:=34, I+N+C+H=:=34, E+J+O+D=:=34, A+F+K+P=:=34,
    P+C+F+I=:=34, L+O+B+E=:=34, H+K+N+A=:=34, D+G+J+M=:=34.   

permutar([],[]). 
permutar([X|Y], Z):-
    permutar(Y,L),
    insertar(X,L,Z). 

insertar(E,L,[E|L]). 
insertar(E, [X|Y], [X|Z]):-
    insertar(E, Y, Z).

Solution

  • Constraint logic programming works good for this kind of problems by dramatically pruning search space.

    Program in ECLiPSe (can be easily translated to work with other modern Prolog systems):

    :- lib(ic).
    
    diabolico([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]) :- 
        Vars = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],
        Vars :: 1..16,
        alldifferent(Vars),
        A+B+C+D #= 34, E+F+G+H #= 34, I+J+K+L #= 34, M+N+O+P #= 34,
        A+E+I+M #= 34, B+F+J+N #= 34, C+G+K+O #= 34, D+H+L+P #= 34,
        M+B+G+L #= 34, I+N+C+H #= 34, E+J+O+D #= 34, A+F+K+P #= 34,
        P+C+F+I #= 34, L+O+B+E #= 34, H+K+N+A #= 34, D+G+J+M #= 34,
        labeling(Vars).
    

    Works instantly:

    [eclipse]: diabolico([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]).
    A = 1
    B = 8
    C = 10
    D = 15
    E = 12
    F = 13
    G = 3
    H = 6
    I = 7
    J = 2
    K = 16
    L = 9
    M = 14
    N = 11
    O = 5
    P = 4
    Yes (0.02s cpu, solution 1, maybe more)