da
xyz » 2 nov 2010, 19:15
Io mi sono confuso sul termine direttivo, trovavo troppe soluzioni. Consideravo direttivo solo P e V escludendo S, invece nel testo incarico, direttivo e eletto sono sinonimi.
Nell'ultima preposizione <<F accetta il posto di P oppure un altro incarico, ma in questo caso se C è P>>, il termine incarico deve essere riferito anche nel caso in cui F non sia eletto (i vari codici proposti hanno questa interpretazione) altrimenti i 7 casi ancora validi:
S=A V=B P=E
S=B V=A P=E
S=A V=C P=E
S=C V=A P=E
S=E V=B P=C
S=C V=F P=D
S=F V=C P=D
quando il candidato C è P il candidato F non ha nessun incarico.
Questa è la mia soluzione scritta in Prolog,
- Codice: Seleziona tutto
% #@ -*- Mode: Prolog -*- vim:ts=8:syntax=prolog:
% Disposizioni di n elementi di classe k
%
% n!/(n-k)!
%
% 6!/(6-3)! = 120
%
comb_rip(_,[]).
comb_rip([X|T], [X|Comb]) :-
comb_rip(T,Comb).
comb_rip([_|T],[X|Comb]) :-
comb_rip(T,[X|Comb]).
perm_rip(L, R):-
comb_rip(L, E),
permutation(E, R).
candidati(Eletti) :-
% tutte le permutazioni degli incarichi
perm_rip([a,b,c,d,e,f], [Seg, Vice, Pres]),
Eletti = [Seg, Vice, Pres],
% A non accetta alcun incarico se E non è 'presidente'
\+ (memberchk(a, Eletti), \+ Pres = e),
% B non accetta alcun incarico se superiore all'incarico di C e
% in nessun modo se F fa' parte del Direttivo
\+ (nth0(IncB, Eletti, b), nth0(IncC, Eletti, c), IncB > IncC),
\+ (memberchk(b, Eletti), memberchk(f, Eletti)),
% C non accetta alcun incarico se entrambi E e F fanno parte
% del Direttivo oppure se F è 'presidente' o se B è 'segretario'
\+ (memberchk(c, Eletti), memberchk(e, Eletti), memberchk(f, Eletti)),
\+ (memberchk(c, Eletti), (Pres = f ; Seg = b)),
% D non vuol essere eletto con C o con E, con un incarico
% inferiore dell'uno o dell'altro
\+ (nth0(IncD, Eletti, d), nth0(IncC, Eletti, c), IncD < IncC),
\+ (nth0(IncD, Eletti, d), nth0(IncE, Eletti, e), IncD < IncE),
% E non vuole essere 'vicepresidente'
% non vuole essere nemmeno 'segretario' se D è nel Direttivo
% non vuole inoltre lavorare con A se F non è nel Direttivo
\+ Vice = e,
\+ (Seg = e, memberchk(d, Eletti)),
\+ (memberchk(f, Eletti), memberchk(e, Eletti), memberchk(a, Eletti)),
% F accetta il posto di 'presidente' oppure un altro incarico (qualsiasi)
% ma in questo caso se C è 'presidente'
(Pres = f ; Pres = c).
go :-
findall(X, candidati(X), P),
write(P).
Il Prolog nasce per risolvere questo tipo di problemi:
http://it.wikipedia.org/wiki/PrologIo uso come interprete Prolog SWI-Prolog,
http://www.swi-prolog.org/Per eseguilo dal terminale direttamente:
- Codice: Seleziona tutto
$> swipl -s candidati.pl -g go -t halt
altrimenti dalla linea di comando di SWI-Prolog:
- Codice: Seleziona tutto
?- [candidati].
?- go.
si ottenine una sola soluzione:
- Codice: Seleziona tutto
[[e,b,c]]
true.
Se si usa GProlog:
http://www.gprolog.org/bisogna sostituire nel codice il predicato 'nth0' con 'nth'.