function solution = solver(n)
global N nA
global A dAdir Astart Aend Ascore bAsr bAsc AAdir AAi
global Abase AscoreUsed
global ArandCalc AdistCent
global nUK UKlist
N=n;
nA=n+2;
A=-ones(nA);
Abase=A;
AAdir=A;
AAi=A;
nUK=0;
UKlist=zeros(20,3);
iAall=1:n;
iAallA=2:n+1;
% And could this be called "programming"?
AAdir(:,1)=1;
AAdir(1,:)=2;
AAdir(:,nA)=3;
AAdir(nA,:)=4;
AAi(1,iAallA)=iAall;
AAi(nA,iAallA)=iAall;
AAi(iAallA,1)=iAall';
AAi(iAallA,nA)=iAall';
dAdir=[nA 1 -nA -1];
Astart=zeros(4,n);
AscoreUsed=false(4,n);
Aend=Astart-1;
Ascore=Astart-1;
Astart(1,:)=2:n+1;
Astart(2,:)=nA+1:nA:nA*n+1;
Astart(3,:)=nA*nA-n:nA*nA-1;
Astart(4,:)=2*nA:nA:nA*nA-1;
bAsr=Astart;
bAsc=Astart;
bAsr(1,:)=1:n;
bAsr([2 4],:)=0;
bAsr(3,:)=-bAsr(1,:);
bAsc=bAsr([2 1 4 3],:);
% wat testvariabelen
ii=abs((0:n+1)-(n+1)/2);
jj=ii';
oA=ones(1,nA);
AdistCent=ii(oA,:)+jj(:,oA);
F2=max(ii(oA,:),jj(:,oA));
ArandCalc=F2(1)-F2;
dirs=[1,2;3 2;1 4;3 4;2 1;4 1;2 3;4 3];
for i=1:8
ZoekStart(dirs(i,1),dirs(i,2));
end
SolveUnkn;
for i=1:2
for dir1=1:4
ZoekRand(dir1);
end
end
SolveUnkn;
onbA=A<0&AAdir<0;
sOnb=sum(onbA(:));
if sOnb==0
solution = max(A(2:1+n,2:1+n),0);
solution(solution>990)=0;
return
end
bErr=0;
for i1=1:n
for dir1=1:4
beamlog(i1,dir1);
end
end
for dir1=1:4
for i1=1:n
beamlog(i1,dir1);
end
end
TestAlle;
SolveUnkn;
if nUK
SolveUnkn2;
end
A(A>990)=2;
A=max(A,Abase);
solution = max(A(2:1+n,2:1+n),0);
solution(solution>990)=2;
function bUpd=SolveUnkn
global N nA
global A dAdir Astart Aend Ascore bAsr bAsc AAdir AAi
global nUK UKlist
global ArandCalc AdistCent
% eerste zoeken of alle onbekenden nog onbekende zijn
% mogelijkheid om links toe te voegen met evt ==0 (niet 999 maken van A)
bUpd=0;
D0=AdistCent(2,2);
iUK=1;
while iUK<=nUK
s=UKlist(iUK,1);
UK=UKlist(iUK,2:end);
UK(UK==0)=[];
aUK=A(UK);
nUKs=aUK>=0&aUK<990;
if all(nUKs) % geen onbekende meer
VerwUnkn(iUK);
iUK=iUK-1;
elseif s<0
if AdistCent(UK)==D0 % hoek
dr=D0-AdistCent(UK+1);
dc1=D0-AdistCent(UK+nA);
dc=dc1*nA;
if A(UK+dr)==0&A(UK+2*dr)>=0
iS=UK+dr-dc;
[iE,s]=beamlog(AAi(iS),AAdir(iS));
A(UK)=s-A(UK+2*dr);
VerwUnkn(iUK);
iUK=iUK-1;
bUpd=1;
elseif A(UK+dc)==0&A(UK+2*dc)>=0
iS=UK+dc-dr;
[iE,s]=beamlog(AAi(iS),AAdir(iS));
A(UK)=s-A(UK+2*dc);
VerwUnkn(iUK);
iUK=iUK-1;
bUpd=1;
end
elseif ArandCalc(UK)==1
%%%%%%%%%%%%
i=1; % breakpoint
else
%%%%%%%%%%%
i=1; % breakpoint
end
elseif sum(~nUKs)==1 % known sum
A(UK(~nUKs))=s-sum(A(UK(nUKs)));
VerwUnkn(iUK);
iUK=iUK-1;
bUpd=1;
end
iUK=iUK+1;
end
function VerwUnkn(i)
global nUK UKlist
if i<nUK
UKlist(i:nUK-1,:)=UKlist(i+1:nUK,:);
end
nUK=nUK-1;
function SolveUnkn2
global N A dAdir Astart Aend Ascore bAsr bAsc nA AAdir AAi
global ArandCalc AdistCent
global nUK UKlist
D0=AdistCent(2,2);
Ulist=UKlist(1:nUK,2:end);
Ulist=unique(Ulist(:))';
if Ulist(1)==0
Ulist(1)=[];
end
B=A;
B(B>990)=-10;
iU=1;
while iU<=length(Ulist)
UK=Ulist(iU);
bUpdated=0;
if AdistCent(UK)==D0 % hoek
dr=D0-AdistCent(UK+1);
dc1=D0-AdistCent(UK+nA);
dc=dc1*nA;
b1=B(UK+dr)>0&B(UK+2*dr)>=0;
b2=B(UK+dc)>0&B(UK+2*dc)>=0;
if b1
if b2
if B(UK+dr)>B(UK+dc) % ?juist?
b1=false;
else
b2=false;
end
end
if ~b2 % looks strange, but is done to do this only once
iS=UK+dr-dc;
DeadlyBeam(iS,UK+dr);
[iE,s]=beamlog(AAi(iS),AAdir(iS));
A(UK)=s-A(UK+2*dr);
bUpdated=1;
end
end
if ~b1
iS=UK+dc-dr;
DeadlyBeam(iS,UK+dc);
[iE,s]=beamlog(AAi(iS),AAdir(iS));
A(UK)=s-A(UK+2*dc);
bUpdated=1;
end
elseif ArandCalc(UK)==1
%%%%(geen minimum bepaling)
dr=ArandCalc(UK+1)-ArandCalc(UK);
if dr==0
di=1;
dc1=ArandCalc(UK+nA)-ArandCalc(UK);
dj=dc1*nA;
else
di=nA;
dj=dr;
end
for dii=[di -di]
UK1=UK+dii;
if B(UK1)>0
s1=B(UK1+dii);
if AdistCent(UK1)==D0|s1>=0
if AdistCent(UK1)==D0
s1=0;
end
iS=UK1-dj;
DeadlyBeam(iS,UK1);
[iE,s]=beamlog(AAi(iS),AAdir(iS));
A(UK)=s-s1;
bUpdated=1;
break;
end
end
end % for dii
end
if bUpdated
while bUpdated&nUK
bUpdated=SolveUnkn;
end
if nUK
Ulist=UKlist(1:nUK,2:end);
Ulist=unique(Ulist(:))';
if Ulist(1)==0
Ulist(1)=[];
end
iU=1;
else
break;
end
else
iU=iU+1;
end
end
function ZoekRand(dir1)
global N A dAdir Astart Aend Ascore bAsr bAsc nA AAdir AAi
d1=dAdir(dir1);
dir2=rem(dir1,2)+1;
d2=dAdir(dir2);
iS0=Astart(dir1,1);
A1=A(iS0+d1+d2*(0:N-1));
if all(A1<=0)&any(A1<0)
%!!!!!!geen zekere bepalingen!!!!
% dit kan uitgebreid worden naar verdere lijnen als nullen tussenin
i=find(A(iS0+d1*2+d2*(0:N-1))~=0);
if length(i)<2
if length(i)==1
% moet betekenen dat er maar een mogelijke positie voor een blok is
if sum(A1~=0)==1
i=find(A1~=0);
if i==1
[iE,s]=beamlog(2,dir1);
else
[iE,s]=beamlog(i-1,dir1);
end
A(iS0+(i-1)*d2+d1)=s;
else
% wat nu?
end
end
else
%return %!!!
i=i(1):i(end);
%for j=i
for j=1:N
beamlog(j,dir1);
end
L=Ascore(dir1,:);
bPos=(L(1:N-2)>0)&(L(1:N-2)==L(3:N))&(L(2:N-1)==0) ...
&(Astart(dir1,1:N-2)==Aend(dir1,1:N-2)) ...
&(Astart(dir1,3:N)==Aend(dir1,3:N)) ... !!!!nog uitbreiden
;
if sum(bPos)==1
iPos=find(bPos);
%A(iS0+d1+d2*(0:N-1))=0;
iS1=iS0+d1+d2*iPos;
%A(iS1)=Ascore(dir1,iPos);
end
end
elseif any(A1<0)
for i1=2:N-1
iS=Astart(dir1,i1)+d1;
if A(iS-d2)>0&A(iS)<0
[iEnd,s]=beamlog(i1,dir1);
if s==0
[iE2,s2]=beamlog(i1+1,dir1);
if s2>0|iE2>0
A(iS)=s2;
else
AddUnknown(iS,-1,1);
end
else
A1=s-A(iS-d2);
if A1<0
if A(iS+d2)>990
AddUnknown([iS+d2 iS-d2],s,1);
A1=999;
else
AddUnknown([iS+d2 iS-d2],s,0);
A1=-1; %!!niet geweten!
end
else
A(iS+d2)=A1;
end
if A1>0
Ascore(dir1,i1+1)=0;
end
end
end
end % for
for i1=N-1:-1:2
iS=Astart(dir1,i1)+d1;
if A(iS+d2)>0&A(iS)<0
[iEnd,s]=beamlog(i1,dir1);
if s==0
[iE2,s2]=beamlog(i1-1,dir1);
if s2>0|iE2>0
A(iS)=s2;
else
AddUnknown(iS,-1,1);
end
else
A(iS)=0;
A1=s-A(iS+d2);
if A1<0
if A(iS-d2)>990
AddUnknown([iS+d2 iS-d2],s,1);
A1=999;
else
AddUnknown([iS+d2 iS-d2],s,0);
A1=-1; % niet geweten!
end
else
A(iS-d2)=A1;
end
if A1>0
Ascore(dir1,i1-1)=0;
end
end
end
end % for
else
Al=A(2:N+1,2:N+1);
sA=sum(Al~=0,2-rem(dir1,2));
i=find(sA); % (faster to be done in newer Matlab....)
if isempty(i)
return
end
if d1>0
i=i(1);
sd1=1;
else
i=i(end);
sd1=-1;
end
if sA(i)>1
iS=Astart(dir2,i);
j=find(A(iS+(1:N)*d2)~=0);
for k=2:length(j)-1
j1=j(k);
iS1=iS+j1*d2;
if A(iS1-d2)>0&A(iS1)<0
[iEnd,s]=beamlog(j1,dir1);
if s==0
AddUnknown(iS1,-1,1);
elseif iEnd==iS % directe weerkaatsing
%(ergens anders is dit op een andere manier getest)
A(iS1)=0;
A1=s-A(iS-d2);
if A1<0
AddUnknown([iS-d2 iS1+d2],s,1);
A1=999;
else
A(iS1+d2)=A1;
end
if A1>0
Ascore(dir1,j1+1)=0;
end
else
j2=AAi(iEnd);
A(iS+(j1:j2)*d2)=0;
A1=s-A(iS1-d2);
if A1<0
AddUnknown([iS+(j2+1)*d2 iS1-d2],s,1);
else
A(iS+(j2+1)*d2)=A1;
end
Ascore(dir1,j2+1)=0;
end
end %
end % while
elseif i+sd1>2&i+sd1<N-1 % one single element on boundary
iNext=i+sd1;
iS=Astart(dir2,iNext);
A1=Ascore(dir2,i-sd1);
[iEnd,s]=beamlog(iNext,dir2);
[iEnd,s]=beamlog(iNext,dir2+2);
end
end
%--------------------
% zoeken naar onmogelijke -1's op rand
%--------------------
A1=A(iS0+d1+d2*(0:N-1));
if all(A1>=0)
return
end
% voor alle zekerheid toch maar alle beams testen
for i1=1:N
if Ascore(dir1,i1)<0
beamlog(i1,dir1);
end
end
iS=iS0+d1;
% zoeken naar opeenvolgende reeksen zonder dubbel-onbekenden
A1=A(iS+d2*(0:N-1));
if all(A1>=0) % (A1 kan veranderd zijn)
return
end
i1=1;
while i1<N
bOK=false;
if A1(i1)<0
bOK=true;
if i1>1&Ascore(dir1,i1-1)==0
A1=DelPt(iS,d2,i1,dir1);
bOK=false;
end
i2=i1+1;
while bOK&i2<=N
if A1(i2)~=0
bOK=false;
elseif i2==N
break
elseif Ascore(dir1,i2)==0 % kan niet==>dit vlak is 0
A1=DelPt(iS,d2,i2-1,dir1);
bOK=i2-2>i1;
break
elseif A1(i2+1)==0
break
elseif A1(i2+1)>0
bOK=false;
end
i2=i2+2;
end
if bOK
if i1>1
A2=LosOp(Ascore(dir1,i1-1:i2-2));
if A2(1)<=0
A1=DelPt(iS,d2,i1,dir1);
i2=i1+1;
else
% nog testen?
end
elseif i2<N
A2=LosOp(Ascore(dir1,i2-1:-1:i1));
%!!!en verder...
end
i1=i2;
end
end
while i1+2<N&i1>1&(A1(i1-1)~=0|A1(i1)~=0)
if A1(i1)<0
if A1(i1-1)==0&Ascore(dir1,i1-1)==0
A1=DelPt(iS,d2,i1,dir1);
else
while i1>1&A1(i1+1)==0&Ascore(dir1,i1+1)==0
A1=DelPt(iS,d2,i1,dir1);
i1=i1-1;
end
end
end
i1=i1+1;
end
i1=i1+1;
end
if all(A1>=0) % (A1 kan veranderd zijn)
return
end
if sum(A1~=0)==1
i=find(A1~=0);
A2=A(iS+d1+d2*(0:N-1));
i2=find(A2~=0);
if isempty(i2)|(i<=i2(1)|i>=i2(end))|A2(i2(1))<0|A2(i2(end))<0
if i==1
A(iS)=Ascore(dir1,2);
else
A(iS+d2*(i-1))=Ascore(dir1,i-1);
end
return
end
end
% 2x2 nullen rond blok op rand, en scores errond zijn verschillend of nul, dan kan er geen blok staan
iS=iS0+d1+d2;
for i1=3:N-200
iS=iS+d2;
if A(iS)<0
if A(iS)<0&all(A(iS+[-2 -1 1 2]*d2)==0) % (A(iS) kan veranderd zijn)
if Ascore(dir1,i1-1)~=Ascore(dir1,i1+1)|Ascore(dir1,i1-1)==0
A(iS)=0;
beamlog(i1-1,dir1);
beamlog(i1+1,dir1);
end
end
end
end
% verder zoeken : als onbekende (op rand) naast nul met score 0, kan er daar geen blokje staan
iS=iS0+d2;
for i1=2:N-100
if A(iS)<0
if (A(iS-d2)==0&Ascore(dir1,i1-1)==0)|(A(iS+d2)==0&Ascore(dir1,i1+1)==0)
A(iS)=0;
end
end
iS=iS+d2;
end
function Auit=LosOp(Ain)
Auit=zeros(size(Ain));
Auit(1)=Ain(1);
for i=3:2:length(Ain)
Auit(i)=Ain(i-1)-Auit(i-2);
end
function A1=DelPt(iS,d2,i1,dir1)
global A N
A(iS+d2*(i1-1))=0;
beamlog(i1,dir1); % herbepalen mogelijke weg
if i1>1
beamlog(i1-1,dir1);
end
if i1<N
beamlog(i1+1,dir1);
end
A1=A(iS+d2*(0:N-1));
function MarkBeam1(iS,iE,s)
% mark simple beam between two endpoints (one deflection, starts at boundary)
global N A dAdir Astart Aend Ascore bAsr bAsc nA AAdir AAi
d1=dAdir(AAdir(iS));
d2=-dAdir(AAdir(iE));
[rrS,ccS]=ind2sub(nA,iS);
[rrE,ccE]=ind2sub(nA,iE);
if abs(d1)>abs(d2)
n1=abs(ccS-ccE);
else
n1=abs(rrS-rrE);
end
for i=1:n1 % waarom nu met een lus?
A(iS)=0;
A(iS+d2)=0;
A(iS-d2)=0;
iS=iS+d1;
end
A(iS)=0;
A(iS+d1)=0;
A(iS-d2)=0;
A(iS-d2+d1)=s;
iS=iS+d2;
while iS~=iE
A(iS)=0;
A(iS+d1)=0;
A(iS-d1)=0;
iS=iS+d2;
end
function AddUnknown(iS,t,chA)
global nUK UKlist
global A
if t>0
A1=A(iS);
iA=A1>=0&A1<990;
if all(iA)
return
elseif sum(~iA)==1 % geen onbekende
A(iS(~iA))=t-sum(A1(iA));
return
elseif any(iA)
% hier kunnen beter alle gekende weggehaald worden (t=t-sum(A(gekenden)))
end
end
if length(iS)+1>size(UKlist,2)
UKlist(1,length(iS)+1)=0;
end
nUK=nUK+1;
UKlist(nUK)=t;
UKlist(nUK,2:length(iS)+1)=iS;
iS=iS(A(iS)<0);
if chA
A(iS)=999;
end
function ZoekStart(dir1,dir2)
global N A dAdir Astart Aend Ascore bAsr bAsc nA AAdir AAi
d1=dAdir(dir1);
d2=dAdir(dir2);
cMax=N;
if d1>0
c0=1;
sd1=1;
else
c0=N;
sd1=-1;
end
if d2>0
i1=1;
sd2=1;
else
i1=N;
sd2=-1;
end
iCnt=0;
while i1<=N&i1>0
iCnt=iCnt+1;
iS=Astart(dir1,i1);
%[rr,ss,BB,nT]=ZoekBeam(iS,dir1);%kan helpen om te beslissen geen beamlog te doen
[iE,s]=beamlog(i1,dir1);
iS1=iS+d1;
if iCnt==1&s>0&A(iS1==0)
[iE2,s2]=beamlog(i1+sd2,dir1);
[iE4,s4]=beamlog(c0+sd1,dir2);
if s2==0
A(iS1+d2)=0;
end
if s4==0
A(iS1+d1)=0;
end
end
if s==-2
%lege lijn - doe niets
i2=i1+sd2;
if i2==1|i2==N
Ascore(dir1,i2)=-2;
dir3=dir1+2;
if dir3>4
dir3=dir3-4;
end
Ascore(dir3,i2)=-2;
i1=i2;
elseif i2+sd2>0&i2+sd2<=N
[iE,s]=beamlog(i2+sd2,dir1);
if s==-2
Ascore(dir1,i2)=-2;
dir3=dir1+2;
if dir3>4
dir3=dir3-4;
end
Ascore(dir3,i2)=-2;
i1=i2+sd2;
end
end
elseif s==0
[iE3,s3]=beamlog(c0,dir2);
if iCnt>1
A(iS+d2+(1:cMax-1)*d1)=0;
else
if s3>0
A(iS1)=0;
%elseif (s2&iE2~=iS1+d2-d1)|(s4&iE4~=iS1+d1-d2)
% % is dit zeker?
% AddUnknown(iS1,-1,1);
end
end
[rr,ss,BB,nT]=ZoekBeam(iS,dir1);
if ss~=0|rr==0
B=BB(BB>0);
B(AAdir(B)>0)=[];
B1=A(B);
B2=BB(BB(:,2)>0,2);
B2(AAdir(B2)>0)=[];
B3=A(B2);
if sum(B1<0)==1&sum(B3<0)==1
AddUnknown(B2(B3<0),-1,1)
end
end
break;
elseif AAdir(iE)==dir1 % direct reflection
A(iS1)=0;
A(iS1+d2)=s;
Ascore(dir1,i1+sd2)=0;
% hier kan ook nog verder gekeken worden (beam vanuit dir2)
break;
else
% ?testen op deflectie in andere richting?
c=abs(AAi(iE)+sd1-c0)+1;
if c-cMax>0
break;
else
cMo=cMax;
cMax=c;
A(iS+(1:c)*d1)=0; % ?is dit nog nodig?
A(iS+d2+(1:c-1)*d1)=0;
iSs=iS+d2+c*d1;
A(iSs)=s;
while 1
iS2=iE+d1*2;
if AAi(iS2)<1
break;
end
[iE2,s1]=beamlog(AAi(iS2),dir2);
if s1
if iE2==iS2
%???wat nu???
break;
elseif AAdir(iE2)==dir2
%???controlleren of dit reeds gebeurde?
nn=abs(AAi(iE2)-AAi(iS2))+1;
A(iSs+(1:nn)*d1)=0;
A(iSs-d2+(1:nn+1)*d1)=0;
s=s1-s;
iSs0=iSs;
iSs=iSs+(nn+1)*d1;
if s<0
AddUnknown([iSs iSs0],s1,1);
s=999;
else
A(iSs)=s;
end
iE=iE2;
else
MarkBeam1(iS2,iE2,s1)
break;
end
else % iets mee te doen?
break;
end
end % while 1
end
end
i1=i1+sd2;
end % while
function [r,s,B,nT]=ZoekBeam(iS0,dir1)
global N A dAdir Astart Aend Ascore bAsr bAsc nA AAdir AAi
s=0;
B=zeros(2*N,3);
nT=0;
d1=dAdir(dir1);
dir2=rem(dir1,2)+1;
d2=dAdir(dir2);
iS=iS0;
B(1,:)=iS0+[-d2 0 d2];
B(2,:)=iS0+d1+[-d2 0 d2];
iB=2;
if AAdir(iS)>0 % wordt dit niet altijd zo opgeroepen (iS op rand)
iS=iS+d1;
if A(iS)>0
s=0;
iB=iB+1;
B=B(1:iB,:);
r=1;
return
elseif A(iS+d2)>0|A(iS-d2)>0
s=sum(max(0,A([iS-d2 iS+d2])));
iB=iB+1;
B(iB,2)=iS0;
B=B(1:iB,:);
r=2;
return
end
end
r=0;
while AAdir(iS)<0
if A(iS+d1)>0
r=3;
iB=iB+1;
s=0;
break;
elseif A(iS+d1+d2)>0
if A(iS+d1-d2)>0
s=s*2+A(iS+d1+d2)+A(iS+d1-d2);
r=4;
iB=iB+1;
B(iB,2)=iS0;
break;
else
d=dir1;
dir1=dir2+2;
dir2=d;
if dir1>4
dir1=dir1-4;
end
d1=dAdir(dir1);
d2=dAdir(dir2);
nT=nT+1;
end
elseif A(iS+d1-d2)>0
d=dir1;
dir1=dir2;
dir2=d;
d1=dAdir(dir1);
d2=dAdir(dir2);
nT=nT+1;
end
iS=iS+d1;
iB=iB+1;
B(iB,:)=iS+[-d2 0 d2];
end
if iB>size(B,1) % op het einde een nul toegevoegd
B(iB,1)=0;
else
B=B(1:iB,:);
end
function TestAlle
global N nA
global A dAdir Astart Aend Ascore bAsr bAsc AAdir AAi
global Abase
global ArandCalc AdistCent
global nUK UKlist
for ii=find(A<0&AAdir<0)'
dRand=ArandCalc(ii);
dHoek=AdistCent(ii)-AdistCent(2,2);
if dHoek==0
dr=AdistCent(ii)-AdistCent(ii+1);
dc=AdistCent(ii)-AdistCent(ii+nA);
elseif dRand==1
end
end
for dir1=1:4
d1=dAdir(dir1);
dir2=rem(dir1,2)+1;
d2=dAdir(dir2);
iS0=Astart(dir1,1);
iS=iS0+d1;
A1=A(iS+d2*(0:N-1));
i1=1;
while i1<N
bOK=false;
if A1(i1)<0
bOK=true;
if i1>1&Ascore(dir1,i1-1)==0
A1=DelPt(iS,d2,i1,dir1);
bOK=false;
end
i2=i1+1;
while bOK&i2<=N
if A1(i2)~=0
bOK=false;
elseif i2==N
break
elseif Ascore(dir1,i2)==0 % kan niet==>dit vlak is 0
A1=DelPt(iS,d2,i2-1,dir1);
bOK=i2-2>i1;
break
elseif A1(i2+1)==0
break
elseif A1(i2+1)>0
bOK=false;
end
i2=i2+2;
end
if bOK
if i1>1
A2=LosOp(Ascore(dir1,i1-1:i2-2));
for j=1:2:length(A2)
i=i1+j-2;
if A2(j)<0
i1=i;
A(iS0+d1+d2*i)=0;
break;
end
A(iS0+d1+d2*i)=A2(j);
end
elseif i2<N
A2=LosOp(Ascore(dir1,i2-1:-1:i1));
%!!!en verder...
end
i1=i2;
end
end
while i1+2<N&i1>1&(A1(i1-1)~=0|A1(i1)~=0)
if A1(i1)<0
if A1(i1-1)==0&Ascore(dir1,i1-1)==0
A1=DelPt(iS,d2,i1,dir1);
else
while i1>1&A1(i1+1)==0&Ascore(dir1,i1+1)==0
A1=DelPt(iS,d2,i1,dir1);
i1=i1-1;
end
end
end
i1=i1+1;
end
i1=i1+1;
end
end
function DeadlyBeam(iS,iKill)
global A dAdir Astart Aend Ascore bAsr bAsc AAi AAdir
global Abase AscoreUsed
B=A;
B(B>990)=-10;
Abase=max(B,Abase);
i0=AAi(iS);
d=AAdir(iS);
beam(bAsr(d,i0),bAsc(d,i0),'high');
A(iKill)=0;
Ascore(:)=-1; %moet slimmer gebeuren
AscoreUsed(:)=0;
function [iEnd,s]=beamlog(i0,d)
global A dAdir Astart Aend Ascore bAsr bAsc AAdir AAi
global AscoreUsed
if Ascore(d,i0)~=-1
s=Ascore(d,i0);
iEnd=Aend(d,i0);
if s>0&~AscoreUsed(d,i0)
b=MarkPosBeam(Astart(d,i0),iEnd,s); % hier toch ook nog eens?
AscoreUsed(d,i0)=b;
AscoreUsed(AAdir(iEnd),AAi(iEnd))=b;
end
return
end
% ? eerst zelf kijken met zoekbeam
[ro,co,s]=beam(bAsr(d,i0),bAsc(d,i0));
if s==0
if ro+co
Ascore(d,i0)=-2;
if rem(d,2)
d1=4-d;
A(i0:i0+2,:)=0; % mogelijk teveel werk!
% beter gebruik maken van richting (meer werk, maar algemener)
else
d1=6-d;
A(:,i0:i0+2)=0; % mogelijk teveel werk!(reeds gedaan)
end
Ascore(d1,i0)=-2;
iEnd=0;
s=-2;
return
else
%
end
end
Ascore(d,i0)=s;
if s==0
iS=Astart(d,i0);
b=MarkPosBeam(iS,0,s);
iEnd=0;
else
[do,io]=find(ro==bAsr&co==bAsc);
iEnd=Astart(do,io);
iS=Astart(d,i0);
b=MarkPosBeam(iS,iEnd,s);
AscoreUsed(d,i0)=b;
AscoreUsed(AAdir(iEnd),AAi(iEnd))=b;
Ascore(do,io)=s;
Aend(do,io)=Astart(d,i0);
end
Aend(d,i0)=iEnd;
function Tinfo=AddTinfo(Tinfo,iT,i)
j=Tinfo(iT,6);
Tinfo(iT,7+j:7+j+length(i)-1)=i;
Tinfo(iT,6)=j+length(i);
function bGevonden=MarkPosBeam(iS,iEnd,ss)
global A dAdir Astart AAi AAdir ArandCalc AdistCent
iS0=iS;
bNogEens=true;
bGevonden=false;
bSisE=iS==iEnd;
while bNogEens;
bNogEens=false;
dir1=AAdir(iS);
d1=dAdir(dir1);
d2=dAdir(rem(dir1,2)+1);
iT=0;
nT=0;
Tinfo=[];
iS1=iS+d1;
if ss==0
if A(iS1)>0
bGevonden=true;
return
elseif AdistCent(1)-AdistCent(iS)<=1
if AAdir(iS1+d2)>0
d2=-d2;
end
if A(iS1+d2)>0
bGevonden=true;
AddUnknown(iS1,-1,0);
return
end
return %!!!!!!nog vervolledigen
% (rij is nul totdat in tweede rij een element ~=0 is)
elseif A(iS1+d2)>0|A(iS1-d2)>0
bGevonden=true;
AddUnknown(iS1,-1,0);
return
end
if A(iS1)<0
ii=iS1+[-d2 d2];
ii(A(ii)>=0)=[];
A(ii)=0;
Tinfo=[ 0 0 0 iS1+d2 ss 0 zeros(size(ii)); ... 0 om aan te geven dat niet verder getest moet worden
iS1 d1 d2 0 ss length(ii) ii];
nT=2;
iT=2; %(eerste mogelijkheid moet niet getest worden!)
end
iEnd=iS;
elseif iS==iEnd
%!!!als ss==1 dan ligt dit blok aan de rand
% het volgende zou ook gebruikt kunnen worden, maar met wat aanpassingen
% hier een vereenvoudigde versie
A(iS1)=0;
if AdistCent(1)-AdistCent(iS)<=1
if AAdir(iS1+d2)>0
d2=-d2;
end
A(iS1+d2)=ss;
bGevonden=1;
return
elseif ss==1
if any(A([iS1-d2 iS1+d2])>=0)
AddUnknown([iS1-d2 iS1+d2],ss,1); % korter dan zelf bepalen, maar trager!!
bGevonden=1;
end
return
elseif any(A([iS1-d2 iS1+d2])>0)
AddUnknown([iS1-d2 iS1+d2],ss,1); % korter dan zelf bepalen, maar trager!!
bGevonden=true;
return
elseif all(A([iS1-d2 iS1+d2])<0)
%Tinfo=[ 0 0 0 iS1+d2 ss 0 0; ... 0 om aan te geven dat niet verder getest moet worden
% iS d1 d2 0 0 1 iS1+d2];
%nT=2;
%iT=2; %(eerste mogelijkheid moet niet getest worden!)
return % te complex
elseif any(A([iS1-d2 iS1+d2])<0) % then both are zero
if A(iS1-d2)<0
d2=-d2;
end
A(iS1+d2)=0;
Tinfo=[ 0 0 0 iS1+d2 ss 0 0; ... 0 om aan te geven dat niet verder getest moet worden
iS1 d1 d2 0 0 1 iS1+d2];
nT=2;
iT=2; %(eerste mogelijkheid moet niet getest worden!)
end % no corner
else % iS~=iEnd
if ss==1|(ss==2&rem(abs(dir1-AAdir(iEnd)),2))
bGevonden=true;
MarkBeam1(iS,iEnd,ss)
return
end
if AdistCent(1)-AdistCent(iEnd)==1 % omwisselen iS en iEnd
iS=iEnd;
iEnd=iS0;
dir1=AAdir(iS);
d1=dAdir(dir1);
d2=dAdir(rem(dir1,2)+1);
end
% bepaling van onmogelijke reflecties via eerste lijn
end
if AdistCent(1)-AdistCent(iS)>1
iS=iS1;
if ss
if AAdir(iS-d1)~=AAdir(iEnd)
A(iS+d1+[-d2 d2])=0;
A(iS+2*d1)=0;
% de volgende lijnen worden evt tweemaal gedaan, maar gemakkelijkt verloop
% (er is trouwens meer dat dubbel gedaan wordt)
dir2=AAdir(iEnd);
d21=dAdir(dir2);
d22=dAdir(rem(dir2,2)+1);
A(iEnd+2*d21+[-d22 d22])=0;
A(iEnd+3*d21)=0;
else
d21=d1;
d22=d2;
end
if nT==0
A(iS)=0;
A(iEnd+d21)=0;
A(iS+d1)=0;
A(iS+d2)=0;
A(iS-d2)=0;
A(iEnd+2*d21)=0;
A(iEnd+d21+d22)=0;
A(iEnd+d21-d22)=0;
end
end
blocks=[]; % ik denk dat blocks eigenlijk niet nodig zijn (som kan wel nuttig zijn!)
% en natuurlijk ook de onbekenden
s=0;
bGetTinfo=false;
bGevonden=true;
bBack=false;
bAangekomen=false;
Tinfo1=[];
while true
iS=iS+d1;
if iS==iEnd
bAangekomen=true;
elseif ArandCalc(iS)==0
bBack=true;
elseif A(iS)>0
%(!)als mogelijkheid dat ss==0, komt dit neer op mogelijk goede aankomst!
if ss==0
bAangekomen=true;
else
bBack=true;
end
elseif ss>0&s>ss&s<990
bBack=true;
end
if bAangekomen
bAangekomen=false;
if nT
if iT>1 % teveel mogelijkheden
bGevonden=false;
break;
elseif iT==nT % opnieuw, nu met de goede (en tracking)
nT=0;
else
i=Tinfo(iT,7:6+Tinfo(iT,6));
A(i)=-1; % terugzetten van waarde
iT=iT+1;
end
bGetTinfo=true;
else % gevonden! en klaar
break
end
end
if ~bGetTinfo&~bBack
if A(iS)<0
if ss==0
break; %!!!!eigenlijk is het "ofwel aangekomen" ofwel niet!!!
else
if nT
Tinfo=AddTinfo(Tinfo,iT,iS);
end
A(iS)=0;
end
end
ii=iS+[-d2 d2];
A1=A(ii);
A1(AAdir(ii)>0)=0;
if A1(1)*A1(2)<0 % you know you don't come back directly
if ~bSisE
i=ii(A1<0);
A1=max(A1,0);
A(i)=0;
if nT
Tinfo=AddTinfo(Tinfo,iT,i);
end
end
end
if all(A1>=0)
if any(A1>0)
if all(A1>0) % tussen twee blokken ingelopen
if bSisE
s=2*s+sum(A1);
if nT
if iT>1 % teveel mogelijkheden
bGevonden=false;
break;
elseif iT==nT % opnieuw, nu met de goede (en tracking)
nT=0;
else
i=Tinfo(iT,7:6+Tinfo(iT,6));
A(i)=-1; % terugzetten van waarde
iT=iT+1;
end
bGetTinfo=true;
else % gevonden! en klaar
blocks(end+1)=iS-d2;
blocks(end+1)=iS+d2;
break
end
else
bBack=true;
end
else % not all A1>0
if A1(1)>0
s=s+A1(1);
d3=d2;
if nT==0
blocks(end+1)=ii(1);
end
else
s=s+A1(2);
d3=-d2;
if nT==0
blocks(end+1)=ii(2);
end
end
iS=iS-d1;
d2=d1;
d1=d3;
end
end
elseif any(A1<0)
if s&s==ss % geen reflecties meer mogelijk
ii=ii(A1<0);
A(ii)=0;
if nT
Tinfo=AddTinfo(Tinfo,iT,ii);
end
elseif nT==0|(~bSisE&ss>0)
%!als bSisE en nT (toevoegen) loopt het fout
iS=iS-d1;
if all(A1<0)
Tinfo1=[iS d2 d1 iS+d1-d2 s 1 iS+d1-d2 0;
iS d1 d2 0 s 2 iS+d1-d2 iS+d1+d2;
iS -d2 d1 iS+d1+d2 s 1 iS+d1+d2 0];
else
if A1(1)~=0
d3=d2;
else
d3=-d2;
end
Tinfo1=[iS d3 d1 iS+d1-d3 s 1 iS+d1-d3;
iS d1 d2 0 s 1 iS+d1-d3];
end
else
break
end
end % if any negative A1
end
if ~isempty(Tinfo1)
if nT==0
iT=0;
Tinfo=Tinfo1;
%Tinfo(1,50)=0;
elseif size(Tinfo,1)<3
if iT<nT
break; % even te moeilijk...
% i=1:size(Tinfo1,2);
% Tinfo=[Tinfo(1:iT,i);Tinfo1;Tinfo(iT+1:end,i)];
else
Tinfo(end+1:end+size(Tinfo1,1),1:size(Tinfo1,2))=Tinfo1;
end
else
break;
end
bGetTinfo=true;
nT=size(Tinfo,1);
iT=iT+1;
Tinfo1=[];
end
if bBack
bBack=false;
% "fout gelopen"
i=Tinfo(iT,7:6+Tinfo(iT,6));
A(i)=-1; % terugzetten van waarde
Tinfo(iT,:)=[];
nT=nT-1;
if nT
% while 1 % lus nu niet nodig, maar eventueel wel na verdere uitbreiding
if nT==1 % 1 mogelijkheid blijft over
iT=1; % opnieuw, nu "voor echt"
nT=0;
% break;
elseif iT<2
% doe niets
% break
elseif Tinfo(iT,1)~=Tinfo(iT-1,1)
b=unique(Tinfo(iT-1:iT,7:6+max(Tinfo(iT-1:iT,6))));
if b(1)==0
b(1)=[];
end
if size(Tinfo,2)<6+length(b)
Tinfo(1,6+length(b)+5)=0; % (wat reserve)
end
iT=iT-1;
Tinfo(iT,7:6+length(b))=b';
Tinfo(iT,6)=length(b);
Tinfo(nT,:)=[];
nT=nT-1;
else
% break;
% end
end
end
bGetTinfo=true;
end
if bGetTinfo
bGetTinfo=false;
iS=Tinfo(iT,1);
if iS==0 % "speciale"
if Tinfo(1,4)
blocks=Tinfo(iT,[4 3]);
blocks(blocks==0)=[];
A(Tinfo(iT,4))=998;
end
break;
end
d1=Tinfo(iT,2);
d2=Tinfo(iT,3);
s=Tinfo(iT,5);
if Tinfo(iT,4)
A(Tinfo(iT,4))=998;
s=s+1; % minimum
if nT==0
blocks(end+1)=Tinfo(iT,7);
end
else
i=Tinfo(iT,7:6+Tinfo(iT,6));
A(i)=0;
end
end
end % while
if nT
i=Tinfo(:,7:6+max(Tinfo(:,6)));
A(i(i>0))=-1; % terugzetten van waarde
end
bGevonden=bGevonden&nT==0; % volledig uitgelopen
if bGevonden&nT==0&~isempty(blocks)
if any(A(blocks)<0|A(blocks)==998)
AddUnknown(blocks,ss,1);
end
end
if iS0~=iEnd&~bGevonden&ss
% iS0~=iEnd omdat dit later toch mogelijk zou kunnen worden
bNogEens=true;
iS=iEnd;
iEnd=iS0;
end
else % enkel eenvoudige mogelijkheid bij aankomen via de rand
bGevonden=true;
if ArandCalc(iS+d1+d2)==0
d2=-d2;
end
while iS+d1-d2~=iEnd
iS=iS+d1;
A(iS)=0;
A(iS+d2)=0;
end
A(iS)=0;
end
end
|