Finish 2006-12-06 09:00:00 UTC

backtotheold_19_cor??

by Stijn Helsen

Status: Passed
Results: 93135.2
CPU Time: 40.9257
Score: 931.519
Submitted at: 2006-12-06 14:49:44 UTC
Scored at: 2006-12-06 15:22:32 UTC

Current Rank: 3366th
Based on: backtotheold_19 (diff)

Comments
Stijn Helsen
06 Dec 2006
an unexpected error... with a simple trial to solve
Please login or create a profile.
Code
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&isempty(Tinfo)	%????what happens
				bGetTinfo=false;
				nT=0;
				break;
			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