Qualche tempo fa ho creato un problema per Codeforces April Fools Day Contest 2014 - "Feed the Golorp": http://codeforces.com/contest/409/problem/I. Si prega di leggere la dichiarazione del problema sul link fornito.Risoluzione di "Feed the Golorp" in Prolog
Il problema doveva essere risolto da persone che non conoscono Prolog. Solo 3 persone sono riuscite a risolvere il problema durante il contest - in Java, Python e C++.
La sfida principale è capire cosa è necessario fare. Per una persona con esperienza di Prolog dovrebbe essere quasi ovvio che il nome di golorp come ?(_-_/___*__):-___>__.
definisce un predicato Prolog e il compito è di trovare valori minimi di variabili tali che i predicati siano soddisfatti. Ci sono alcuni dettagli: di nuovo, leggi la dichiarazione del problema.
In realtà risolvere il problema dopo aver compreso l'obiettivo non è così banale. Algoritmicamente il compito è quello di ordinare topologicamente le variabili in base ai vincoli. Il nome di Golorp può essere lungo fino a 1024 caratteri, quindi è necessario un algoritmo decentemente efficiente.
Ho scritto la mia soluzione di riferimento in Python con espressioni regolari. Ma dopo la gara ho iniziato a chiedermi come risolvere il problema in Prolog.
A causa della lunghezza possibile del nome di golorp fino a 1024 caratteri utilizzando solo il backtracking di Prolog per bruteforce, tutte le possibilità non sembrano possibili - è probabilmente necessaria la programmazione della logica dei vincoli .
Se riesco a estrarre l'elenco di tutte le variabili e l'elenco di coppie di variabili dalle disuguaglianze, posso risolverlo. Per esempio in Eclipse CLP:
:- lib(ic).
solve(Vars, Ineqs, Result) :-
Vars :: 0..9,
(foreach((A, B), Ineqs) do
A #< B),
labeling(Vars),
concat_string(Vars, Result).
[eclipse]: Vars = [__, ___, __, ___], Ineqs = [(__, ___)], solve(Vars, Ineqs, Result).
Vars = [0, 1, 0, 1]
__ = 0
___ = 1
Ineqs = [(0, 1)]
Result = "0101"
Ma io non sono sicuro di come ottenere Vars = [__, ___, __, ___]
e Ineqs = [(__, ___)]
da ?(__+___+__-___):-___>__.
senza troppo codice. term_variables/2
perde le variabili duplicate. DCG?
Oppure esiste un modo completamente diverso e migliore per risolvere il puzzle in Prolog? (non necessariamente in ECLiPSe CLP).
Aggiornamento: paio di grandi esempi di prova:
?(_____________________*_________________________*________________________*___________________*_________________*__________________*___________________________*___*__*____________________*_________________________*_______________*____*___________*_____________*______*_____*_______________*____________*__________________*___________________________*___________________________):-_____>__,_______________<___________________,__>___________,________________________>______,_____________>______,____________________<_________________________,_________________<__________________,_____________<___,____<_________________________,______>____________,________________________>_________________________,_____<____________________,__<____________,_____________________>____________,__________________>_______________,_____>___,___________<_______________,_________________________>____,____<___________________,________________________>___________________________,____________>___________________________,_____<_______________.
Risultato: 3898080517870043672800
?(___*__*_____*____*_____*___*___*_____*___*___*___*__*___*_____*___*_____*____*___*____*_____*_____*____*_____*____*____*____*___*___*__*___*____*__*_____*_____*____*____*___*__*____*___*___*____*_____*_____*____*___*__*_____*____*__*_____*___*___*___*_____*____*___*_____*_____*___*___*___*____*__*_____*_____*__*___*__*__*_____*____*_____*___*__*_____*_____*__*____*___*____*_____*_____*___*___*___*_____*__*__*__*__*___*_____*__*___*___*____*_____*___*__*_____*_____*_____*_____*_____*__*__*___*___*_____*____*___*__*___*__*___*_____*__*_____*_____*_____*____*____*___*___*_____*____*____*__*__*_____*___*__*___*_____*_____):-____>_____,___>____.
Risultato: 2001022022202020121001011122021000112012210012001002220120022210000200010200001210022200000200221020000000022012020200000112201100020200
Grazie, ho imparato molto dalla tua risposta. –