function f=solver(D,B,M,ID)
if B<=1, f=ones(1,D); return; end
[cs,ng,fr,f,lsr]=findcs(D,B,M,ID);
if lsr>=D | ng>=M | isempty(cs), return; end
for i=1:size(cs,1)
[ind,ng]=ffc(f,fr,cs(i,2),cs(i,1),lsr,M,ID); f(fr(ind))=cs(i,1); fr(ind)=[];
if ng>=M, for j=i+1:size(cs,1)
f(fr(1:cs(j,2)))=cs(j,1); fr=fr(cs(j,2)+1:end); end; return; end;
lsr=lsr+cs(i,2); if lsr>=D, return; end; end
function [ind,ng]=ffc(gs,x,n,col,b0,gsLim,ID)
if length(x)==n, ind=1:n; ng=0; return; end;
if (length(x)<13) & (n~=1)
[ind,ng]=ffclp(gs,x,n,col,b0,gsLim,ID);
return;
end
i=floor(length(x)/2); g=gs; g(x(1:i))=col; [b,w,ng]=scoreme(g,ID);
nv=n-b+b0;
if b>b0, if ng>=gsLim, ind=[1:b-b0,(i+1:i+nv)]; return; end;
[i1,ng]=ffc(gs,x(1:i),b-b0,col,b0,gsLim,ID);
if ng>=gsLim, ind=[i1,(i+1:i+nv)]; return; end
elseif ng>=gsLim, ind=i+1:i+nv; return;
else
i1=[];
end
if nv, [i2,ng]=ffc(gs,x(i+1:end),nv,col,b0,gsLim,ID); i2=i2+i;
else
i2=[]; end;
ind=[i1 i2];
function [cs,ng,fr,a,lsr]=findcs(np,nc,gsLim,ID)
fr=1:np; cs=zeros(nc,2); a=ones(1,np); T=0; j=0; k=1; lsr=0; l=1; mc=0;
for i=1:nc-1
a(fr)=i;
if l<=j
a(fr(k))=cs(l,1); [b,w,ng]=scoreme(a,ID); b=b+w-1-lsr;
if w
if w>1
a(fr(k))=i; fr(k)=[]; lsr=lsr+1; b=b-1; T=T+1;
else
k=k+1;
end
else
fr(k)=[]; cs(l,2)=cs(l,2)-1; lsr=lsr+1;
if cs(l,2)==0,
mc=cs(l,1); l=l+1; k=1; end; end;
else
[b,w,ng]=scoreme(a,ID); b=b-lsr;
end
if b, j=j+1; cs(j,:)=[i,b]; T=T+b;
else
mc=i;
end
if ng>=gsLim | T>=np, break; end;
end
if T<np, j=j+1; cs(j,:)=[nc,np-T]; end;
if np==1, a=cs(1,1); lsr=1; return; end;
cs=cs(l:j,:); if isempty(cs), lsr=np; return;
elseif size(cs,1)==1; a(fr)=cs(1,1); lsr=np; return;
end
if ng>=gsLim, j=1;
for i=1:size(cs,1)
a(fr(j:j+cs(i,2)-1))=cs(i,1); j=j+cs(i,2);
end
lsr=np; return;
end
if mc, a(fr)=mc; [i,j]=sort(-cs(:,2)); cs=cs(j,:);
else
cs=cs([2 1 3:end],:); i=k; n1=cs(1,2); n2=cs(2,2); c1=cs(1,1); c2=cs(2,1); a(fr)=c1;
while n2
a(fr(i))=c2; [b,w,ng]=scoreme(a,ID);
if w==0, fr(i)=[]; n2=n2-1; lsr=lsr+1;
else
a(fr(i))=c1; i=i+1;
end
if ng>=gsLim, a(fr(1:n2))=c2; fr=fr(n2+1:end); for i=3:size(cs,1)
a(fr(1:cs(i,2)))=cs(i,1); fr=fr(cs(i,2)+1:end); end;
lsr=np; return; end; end; a(fr)=c2; cs(2,:)=[]; [i,j]=sort(-cs(:,2)); cs=cs([j(end);j(1:end-1)],:);
if size(cs,1)==1, a(fr)=cs(1,1); lsr=np; end;
end
function [ind,ng]=ffclp(gs,index,n,cl,b0,gsLim,ID)
ng=0;
guesses=[];
l=length(index);
for i=1:l
guesses=[guesses, mod((1:2^l)',2^i)>=2^(i-1)];
end;
answers=guesses(find(sum(guesses,2)==n),1:l)';
count=0;
while (size(answers,2)~=1) & (ng<gsLim)
count=count+1;
if count==1
bestguess=(1:l)>l/2;
elseif count==2
bestguess=((1:l)<=round(l/4))+((1:l)>round(3*l/4));
else
[m,bestguessn]=min(sum(histc(guesses*answers,0:n,2).^2,2));
bestguess=guesses(bestguessn,1:l);
end
g=gs; g(index(find(bestguess)))=cl;
[b,w,ng]=scoreme(g,ID);
answers=answers(1:l,find(bestguess*answers==b-b0));
end
ind=find(answers(1:l,1+floor(rand(1)*size(answers,2))))';
|