| Code: | function W = solver(B)
W=zeros(0,4);
S=grade(B,W);
W1=chainsolver(B);
W2=advsolver(B);
S1=grade(B,W1);
S2=grade(B,W2);
if S1<S2 & S1<S
W=W1;
elseif S2<S1 & S2<S
W=W2;
end
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
function W = advsolver(B)
W = zeros(0,4);
x=B;
swSr=unique(x);
swSr=swSr(find(swSr));
for count=1:numel(swSr)
PIN=swSr(count);
POS=find(x==PIN);
[I,J]=ind2sub(size(x),POS);
in=[I J];
for i=1:size(in,1)-1
tempin=in(i:i+1,:);
out=ili(tempin);
[output,intersect]=sSs(x,PIN,out);
if isempty(intersect)
W=[W;output];
else
break
end
end
end
function out=ili(in)
out=[];
for i=1:size(in)-1
rDr=in(i,1); RdR=in(i,2);
cFG=in(i+1,1); aaa=in(i+1,2);
if rDr==cFG & RdR<aaa %exactly left
for i=RdR:aaa-1
out(end+1,1:4)=[rDr i cFG i+1];
end
elseif rDr==cFG & RdR>aaa %exactly right
for i=RdR:-1:aaa+1
out(end+1,1:4)=[rDr i cFG i-1];
end
elseif rDr<cFG & RdR==aaa %exactly up
for i=rDr:cFG-1
out(end+1,1:4)=[i RdR i+1 aaa];
end
elseif rDr>cFG & RdR==aaa %exactly down
for i=rDr:-1:cFG+1
out(end+1,1:4)=[i RdR i-1 aaa];
end
elseif rDr<cFG & RdR<aaa %up left
for i=RdR:aaa-1
out(end+1,1:4)=[rDr i rDr i+1];
end
rDr=out(end,3);
RdR=out(end,4);
for i=rDr:cFG-1
out(end+1,1:4)=[i RdR i+1 RdR];
end
elseif rDr<cFG & RdR>aaa %up right
for i=RdR:-1:aaa+1
out(end+1,1:4)=[rDr i rDr i-1];
end
rDr=out(end,3);
RdR=out(end,4);
for i=rDr:cFG-1
out(end+1,1:4)=[i RdR i+1 RdR];
end
elseif rDr>cFG & RdR<aaa %down left
for i=rDr:-1:cFG+1
out(end+1,1:4)=[i RdR i-1 RdR];
end
rDr=out(end,3);
RdR=out(end,4);
for i=RdR:aaa-1
out(end+1,1:4)=[rDr i rDr i+1];
end
elseif rDr>cFG & RdR>aaa %down right
for i=rDr:-1:cFG+1
out(end+1,1:4)=[i RdR i-1 RdR];
end
rDr=out(end,3);
RdR=out(end,4);
for i=RdR:-1:aaa+1
out(end+1,1:4)=[rDr i rDr i-1];
end
end
end
function [output,intersect]=sSs(mMm,ll1,nNn)
output=nNn;
intersect=[];
for i=1:size(nNn,1)
r=nNn(i,3);
c=nNn(i,4);
if mMm(r,c)~=0 & mMm(r,c)~=ll1
intersect(end+1,1:3)=[r c mMm(r,c)];
end
end
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
function W = chainsolver(B)
W = zeros(0,4);
pin=unique(B);
pin=pin(find(pin));
for i=1:numel(pin)
nht=pin(i);
jessop=ccdff(B,nht);
chain=ffccd(B,nht);
in=[];
if ~isempty(jessop)
[mv,mi]=max(chain(:,2));
start=mi;
to=start+chain(mi,2)-1;
if size(jessop,1)>to
jessop=jessop(start:to,:);
end
for j=1:size(jessop,1)
[r,c]=ind2sub(size(B),jessop(j,1));
in(end+1,1:2)=[r c];
end
W=[W;connection(in)];
end
end
[ro,co] = size(B);
if any(any(W(:,[1 3])>ro)) || any(any(W(:,[2 4])>co)) || any(any(W<1))
W=zeros(0,4);
end
%------------------------------------------------------------------------
function chain=ccdff(caramba,nht)
chain=[];
ind=find(caramba==nht);
count=1;
while count<numel(ind)
base=ind(count);
out=peko(caramba,base);
if numel(out)>0 & ~isempty(setdiff(out,base)) %thers's matching neighbor
out=setdiff(out,base);
chain(end+1,1:2)=[base numel(out)];
end
count=count+1;
end
%--------------------------------------------------------------------
function jessop=ffccd(caramba,nht)
chain=[];
jessop=[];
rowsize=size(caramba,1);
colsize=size(caramba,2);
ind=find(caramba==nht);
count=1;
while count<numel(ind)
base=ind(count);
out=peko(caramba,base);
if numel(out)>0 & ~isempty(setdiff(out,base)) %thers's matching neighbor
out=setdiff(out,base);
chain(end+1,1:2)=[base numel(out)];
end
count=count+1;
end
%create recursive chain upto depth D
value=[];
if ~isempty(chain)
D=6;
for iter=1:10
i=1;
base=chain(i,1);
out=bKp(base,D,rowsize);
[mv,mi]=intersect(chain(:,1),out);
count=chain(i,2)+sum(chain(mi,2))-numel(mi)+1;
value(end+1,1:2)=[base count];
newchainelem=setdiff(1:size(chain,1),[i mi]);
chain=chain(newchainelem,:);
if isempty(chain), break, end
end
end
jessop=value;
%-------------------------------------
function out=bKp(base,D,rowsize)
T=[];
for i=1:D
for j=1:numel(base)
T=[T base(j)+1 base(j)+rowsize];
end
base=T;
end
out=unique(T);
%-------------------------------------
function out=peko(caramba,index)
out=[];
rowsize=size(caramba,1);
colsize=size(caramba,2);
nht=numel(caramba);
% UP
newindex=index-1;
if newindex>=1 & newindex<=nht & caramba(newindex)==caramba(index)
out(end+1)=newindex;
end
% DOWN
newindex=index+1;
if newindex>=1 & newindex<=nht & caramba(newindex)==caramba(index)
out(end+1)=newindex;
end
% LEFT
newindex=index-rowsize;
if newindex>=1 & newindex<=nht & caramba(newindex)==caramba(index)
out(end+1)=newindex;
end
% RIGHT
newindex=index+rowsize;
if newindex>=1 & newindex<=nht & caramba(newindex)==caramba(index)
out(end+1)=newindex;
end
%-------------------------------------
function out=connection(in)
out=[];
for i=1:size(in)-1
fromrow=in(i,1);
fromcol=in(i,2);
newin=in(i+1:end,:);
rowmatch=find(fromrow==newin(:,1));
if ~isempty(rowmatch)
torow=newin(rowmatch(1),1);
tocol=newin(rowmatch(1),2);
out(i,1:4)=[fromrow fromcol torow tocol];
else
colmatch=find(fromcol==newin(:,2));
if ~isempty(colmatch)
torow=newin(colmatch(1),1);
tocol=newin(colmatch(1),2);
out(i,1:4)=[fromrow fromcol torow tocol];
end
end
end |