venerdì 20 giugno 2008

Problema delle N regine in PROLOG

/*
Soluzione in Prolog del problemma delle N Queens

Dato un numero naturale N, queens(N,Q) restituisce una
possibile disposizione di N regine su una scacchiera
N*N, in modo che nessuna sia sotto lo scacco di un'altra.
La disposizione sara' rappresentata come una lista
Q = [q1,...,qN] di numeri nell'intervallo fra 1 e N
dove qi rappresenta il numero di riga della
regina della colonna i-esima.

*/

/*
permutation(L1,L2) genera una permutazione L2 della lista L1; predefinita
nel linguaggio. Lo potevamo anche definire noi, come abbiamo visto a lezione.
*/


queens(N,Q) :-
list_int(1,N,L), permutation(L,Q), sicure(Q).


/* list_int(M,N,L) genera la lista L di tutti i numeri interi fra M e N se M <= N,
altrimenti generea la lista vuota.
*/

list_int(M,N,L) :-
M > N, L = [].
list_int(M,N,L) :-
M =< N, L = [M|L1], M1 is M+1, list_int(M1,N,L1).

/*
sicure(Q) controlla che la lista Q rappresenti una disposizione sicure delle reggine,
ossia che nessuna sia sotto lo scacco di un altra.
*/

sicure([]).
sicure([X|Q]) :-
no_attack(X,Q), sicure(Q).

/*
no_attack(X,Q) controlla che la regina in posizione di riga X
non sia sotto lo scacco di nessuna regina della lista Q
*/

no_attack(X,Q) :-
no_attack_aus(1,X,Q).
no_attack_aus(_,_,[]).
no_attack_aus(DIST,X,[Y|Q]) :-
X - Y =\= DIST, Y - X =\= DIST, DIST1 is DIST+1, no_attack_aus(DIST1,X,Q).

Nessun commento: