%You will be given a board that consists of N x M cells.
% Each cell contains a color (Red, Yellow or Blue).
% Your task is to find color cycles for any of the three colors
% For example, as shown in the picture, cells 2,1-> 2,2-> 3,2-> 3,1 form a blue cycle
% Another cycle could be cells 2,0-> 2,1-> 3,1-> 3,0
% Note that yellow and red colors do not form cycles in this example.
%Your code should print at least one of these cycles including its color (if any) or no cycles
% exist
% Cycle defined by the following cells c1, c2, ..., ck must have the following:
%These cells are different (no duplicates)--
%At least 4 cells (or more)
%All cells have the same color
%The cells are adjacent to each other
%You are allowed to use the search engine for uninformed search that we given in the lab
%Your main tasks are:----
%Design input
%Design state representation
%Design moves
%Design output
%Helper
replace(0,[_|T],X,[X|T]).
replace(Index,[H|T],X,[H|R]):-
Index>0,NewIndex is Index - 1,
replace(NewIndex,T,X,R).
getLast([H],H):-!.
getLast([_|T],Last):-
getLast(T,Last).
fill([],_,[]):-!.
fill([_|T],X,[X|Done]):-
fill(T,X,Done).
:-dynamic n/1.
:-dynamic m/1.
:-dynamic path/1.
setPath(Path):-
retractall(path(_)),
assertz(path(Path)).
isValid(I,J):-
n(N),m(M),
I<N,I>=0,J<M,J>=0.
getCell(I,J,Grid,Output):-
nth0(I,Grid,ROW),
nth0(J,ROW,Output).
detectCycle(N,M,Grid):-
retractall(n(_)),retractall(m(_)),
assertz(n(N)),assertz(m(M)),
detectCycle(Grid).
visit(I,J,Visited,NewVisited):-
nth0(I,Visited,Row),
replace(J,Row,true,NewRow),
replace(I,Visited,NewRow,NewVisited).
detectCycle(Grid):-
n(N),m(M),
length(ROW,M),
fill(ROW,false,NewRow),
length(V,N),
fill(V,NewRow,Visited),
((tryAll(Grid,Visited,-1,-1,[]), path(Path),length(Path,L),L>=4)->
write('Cycle Found:'),
writeln(Path);
write('No Cycle Found')
).
%down
move(I,J,X,J):-
X is I + 1.
%up
move(I,J,X,J):-
X is I - 1.
%right
move(I,J,I,Y):-
Y is J+1.
% left
move(I,J,I,Y):-
Y is J -1.
tryAll(Grid,Visited,ParentX,ParentY,Path):-
n(N),m(M),
setPath([]),
between(0,N,I),
between(0,M,J),
searchCycle(I,J,Grid,Visited,ParentX,ParentY,Path).
searchCycle(I,J,Grid,Visited,ParentX,ParentY,Path):-
writeln([I,J]),
isValid(I,J),
getCell(I,J,Grid,Color),
getCell(I,J,Visited,IsVisited),
\+IsVisited, % not visited before
visit(I,J,Visited,NewVisited),
findall(_,
(
move(I,J,X,Y), %next state
isValid(X,Y), % check next
path(GlobalPath),
GlobalPath == [], % no cycles found
getCell(X,Y,Grid,CurrColor),
getCell(X,Y,NewVisited,CurrIsVisited),
(
Color == CurrColor,
NextPath = [[I,J]|Path],
CurrIsVisited == true,
\+(ParentX = X , ParentY = Y)->
(getLast(NextPath,Last),Last == [X,Y] -> setPath(NextPath))
;
(Color == CurrColor -> NextPath = [[I, J] | Path] ),
searchCycle(X,Y,Grid,Visited,I,J,NextPath)
)
)
,Temp),
length(Temp,L),
L>0.
JVlvdSB3aWxsIGJlIGdpdmVuIGEgYm9hcmQgdGhhdCBjb25zaXN0cyBvZiBOIHggTSBjZWxscy4KJSBFYWNoIGNlbGwgY29udGFpbnMgYSBjb2xvciAoUmVkLCBZZWxsb3cgb3IgQmx1ZSkuCiUgWW91ciB0YXNrIGlzIHRvIGZpbmQgY29sb3IgY3ljbGVzIGZvciBhbnkgb2YgdGhlIHRocmVlIGNvbG9ycwolIEZvciBleGFtcGxlLCBhcyBzaG93biBpbiB0aGUgcGljdHVyZSwgY2VsbHMgMiwxLT4gMiwyLT4gMywyLT4gMywxIGZvcm0gYSBibHVlIGN5Y2xlCiUgQW5vdGhlciBjeWNsZSBjb3VsZCBiZSBjZWxscyAyLDAtPiAyLDEtPiAzLDEtPiAzLDAKJSBOb3RlIHRoYXQgeWVsbG93IGFuZCByZWQgY29sb3JzIGRvIG5vdCBmb3JtIGN5Y2xlcyBpbiB0aGlzIGV4YW1wbGUuCiAlWW91ciBjb2RlIHNob3VsZCBwcmludCBhdCBsZWFzdCBvbmUgb2YgdGhlc2UgY3ljbGVzIGluY2x1ZGluZyBpdHMgY29sb3IgKGlmIGFueSkgb3Igbm8gY3ljbGVzCiUgZXhpc3QKJSBDeWNsZSBkZWZpbmVkIGJ5IHRoZSBmb2xsb3dpbmcgY2VsbHMgYzEs4oCJYzIs4oCJLi4uLOKAiWNrIG11c3QgaGF2ZSB0aGUgZm9sbG93aW5nOgolVGhlc2UgY2VsbHMgYXJlIGRpZmZlcmVudCAobm8gZHVwbGljYXRlcyktLQolQXQgbGVhc3QgNCBjZWxscyAob3IgbW9yZSkKICVBbGwgY2VsbHMgaGF2ZSB0aGUgc2FtZSBjb2xvcgogJVRoZSBjZWxscyBhcmUgYWRqYWNlbnQgdG8gZWFjaCBvdGhlcgogJVlvdSBhcmUgYWxsb3dlZCB0byB1c2UgdGhlIHNlYXJjaCBlbmdpbmUgZm9yIHVuaW5mb3JtZWQgc2VhcmNoIHRoYXQgd2UgZ2l2ZW4gaW4gdGhlIGxhYgogJVlvdXIgbWFpbiB0YXNrcyBhcmU6LS0tLQogJURlc2lnbiBpbnB1dAogJURlc2lnbiBzdGF0ZSByZXByZXNlbnRhdGlvbgogJURlc2lnbiBtb3ZlcwogJURlc2lnbiBvdXRwdXQKCiVIZWxwZXIKCnJlcGxhY2UoMCxbX3xUXSxYLFtYfFRdKS4KcmVwbGFjZShJbmRleCxbSHxUXSxYLFtIfFJdKTotCiAgICBJbmRleD4wLE5ld0luZGV4IGlzIEluZGV4IC0gMSwKICAgIHJlcGxhY2UoTmV3SW5kZXgsVCxYLFIpLgoKCmdldExhc3QoW0hdLEgpOi0hLgpnZXRMYXN0KFtffFRdLExhc3QpOi0KICAgIGdldExhc3QoVCxMYXN0KS4KCgpmaWxsKFtdLF8sW10pOi0hLgpmaWxsKFtffFRdLFgsW1h8RG9uZV0pOi0KICAgIGZpbGwoVCxYLERvbmUpLiAgICAgCgoKOi1keW5hbWljIG4vMS4KOi1keW5hbWljIG0vMS4KCjotZHluYW1pYyBwYXRoLzEuCgoKc2V0UGF0aChQYXRoKTotCiAgICByZXRyYWN0YWxsKHBhdGgoXykpLAogICAgYXNzZXJ0eihwYXRoKFBhdGgpKS4KCgoKCgppc1ZhbGlkKEksSik6LQogICAgbihOKSxtKE0pLAogICAgSTxOLEk+PTAsSjxNLEo+PTAuCgpnZXRDZWxsKEksSixHcmlkLE91dHB1dCk6LQogICAgbnRoMChJLEdyaWQsUk9XKSwKICAgIG50aDAoSixST1csT3V0cHV0KS4gICAgCgpkZXRlY3RDeWNsZShOLE0sR3JpZCk6LQogICAgcmV0cmFjdGFsbChuKF8pKSxyZXRyYWN0YWxsKG0oXykpLAogICAgYXNzZXJ0eihuKE4pKSxhc3NlcnR6KG0oTSkpLAogICAgZGV0ZWN0Q3ljbGUoR3JpZCkuCgoKCgp2aXNpdChJLEosVmlzaXRlZCxOZXdWaXNpdGVkKTotCiAgICBudGgwKEksVmlzaXRlZCxSb3cpLAogICAgcmVwbGFjZShKLFJvdyx0cnVlLE5ld1JvdyksCiAgICByZXBsYWNlKEksVmlzaXRlZCxOZXdSb3csTmV3VmlzaXRlZCkuCgoKCmRldGVjdEN5Y2xlKEdyaWQpOi0KICAgIG4oTiksbShNKSwKICAgIGxlbmd0aChST1csTSksCiAgICBmaWxsKFJPVyxmYWxzZSxOZXdSb3cpLAogICAgbGVuZ3RoKFYsTiksCiAgICBmaWxsKFYsTmV3Um93LFZpc2l0ZWQpLAoKICAgICgodHJ5QWxsKEdyaWQsVmlzaXRlZCwtMSwtMSxbXSksIHBhdGgoUGF0aCksbGVuZ3RoKFBhdGgsTCksTD49NCktPgogICAgICAgIHdyaXRlKCdDeWNsZSBGb3VuZDonKSwgCiAgICAgICAgd3JpdGVsbihQYXRoKTsKICAgICAgICB3cml0ZSgnTm8gQ3ljbGUgRm91bmQnKQogICAgKS4KICAgIAogJWRvd24KbW92ZShJLEosWCxKKTotCiAgICBYIGlzIEkgKyAxLgogJXVwCm1vdmUoSSxKLFgsSik6LQogICAgWCBpcyBJIC0gMS4KCiVyaWdodAogbW92ZShJLEosSSxZKTotCiAgICAgWSBpcyBKKzEuCiUgbGVmdAogbW92ZShJLEosSSxZKTotCiAgICBZIGlzIEogLTEuCgoKCnRyeUFsbChHcmlkLFZpc2l0ZWQsUGFyZW50WCxQYXJlbnRZLFBhdGgpOi0KICAgIG4oTiksbShNKSwKICAgIHNldFBhdGgoW10pLAogICAgYmV0d2VlbigwLE4sSSksCiAgICBiZXR3ZWVuKDAsTSxKKSwKICAgIHNlYXJjaEN5Y2xlKEksSixHcmlkLFZpc2l0ZWQsUGFyZW50WCxQYXJlbnRZLFBhdGgpLgoKCiAgCgpzZWFyY2hDeWNsZShJLEosR3JpZCxWaXNpdGVkLFBhcmVudFgsUGFyZW50WSxQYXRoKTotCiAgICB3cml0ZWxuKFtJLEpdKSwKICAgIGlzVmFsaWQoSSxKKSwKICAgIGdldENlbGwoSSxKLEdyaWQsQ29sb3IpLAogICAgZ2V0Q2VsbChJLEosVmlzaXRlZCxJc1Zpc2l0ZWQpLAogICAgXCtJc1Zpc2l0ZWQsICUgbm90IHZpc2l0ZWQgYmVmb3JlCiAgICB2aXNpdChJLEosVmlzaXRlZCxOZXdWaXNpdGVkKSwKICAgIGZpbmRhbGwoXywKICAgICAgICAoCiAgICAgICAgbW92ZShJLEosWCxZKSwgJW5leHQgc3RhdGUKICAgICAgICBpc1ZhbGlkKFgsWSksICUgY2hlY2sgbmV4dCAKICAgICAgICBwYXRoKEdsb2JhbFBhdGgpLAogICAgICAgIEdsb2JhbFBhdGggPT0gW10sICUgbm8gY3ljbGVzIGZvdW5kCiAgICAgICAgZ2V0Q2VsbChYLFksR3JpZCxDdXJyQ29sb3IpLAogICAgICAgIGdldENlbGwoWCxZLE5ld1Zpc2l0ZWQsQ3VycklzVmlzaXRlZCksCiAgICAgICAgKAogICAgICAgICAgICBDb2xvciA9PSBDdXJyQ29sb3IsCiAgICAgICAgICAgIE5leHRQYXRoID0gW1tJLEpdfFBhdGhdLAogICAgICAgICAgICBDdXJySXNWaXNpdGVkID09IHRydWUsCiAgICAgICAgICAgIFwrKFBhcmVudFggPSBYICwgUGFyZW50WSA9IFkpLT4gCiAgICAgICAgICAgIChnZXRMYXN0KE5leHRQYXRoLExhc3QpLExhc3QgPT0gW1gsWV0gLT4gc2V0UGF0aChOZXh0UGF0aCkpCiAgICAgICAgICAgIDsKICAgICAgICAgICAgKENvbG9yID09IEN1cnJDb2xvciAtPiBOZXh0UGF0aCA9IFtbSSwgSl0gfCBQYXRoXSApLAogICAgICAgICAgICBzZWFyY2hDeWNsZShYLFksR3JpZCxWaXNpdGVkLEksSixOZXh0UGF0aCkKCiAgICAgICAgKQogICAgKQogICAgCiAgICAsVGVtcCksCiAgICBsZW5ndGgoVGVtcCxMKSwKICAgIEw+MC4KCgoKCgoKICAgIAogICAg