[an error occurred while processing this directive]
Listing TZ.PAS
{$N+}
Program TZ;
const NrMaxPietre=1E18;
DimMax=87;
type Indice=0..DimMax+2;
ReprezentareF=array[Indice] of 0..1;
SirFibonacci=array[Indice] of comp;
var n,m,p,a,b:comp;
s:SirFibonacci;
rn,rm:ReprezentareF;
fout:Text; nume:string;
procedure GenerareSirFibonacci;
{ genereaza in vectorul s termenii sirului }
{ Fibonacci necesari pentru a reprezenta in }
{ sistemul de numeratie Fibonacci numerele pana }
{ la 1E18 }
var i:Indice;
begin
s[1]:=1; s[2]:=2;
for i:=3 to DimMax+2 do
s[i]:=s[i-1]+s[i-2]
end;
procedure Reprezinta(x:comp;
var rx:ReprezentareF);
{ determina in rx reprezentarea numarului x in }
{ sistemul de numeratie Fibonacci }
var i:Indice;
begin
i:=DimMax;
while i>0 do
begin
if s[i]>x
then rx[i]:=0
else begin rx[i]:=1; x:=x-s[i] end;
Dec(i)
end
end;
procedure Citire;
var f:Text; nume:string;
begin
Write('fisier intrare='); Readln(nume);
Assign(f,nume); Reset(f);
Readln(f,n,m);
Close(f)
end;
function NrZero(var rx:ReprezentareF):Indice;
{ returneaza numarul de zerouri "finale" }
{ ale reprezentarii rx }
var i:Indice;
begin
i:=1;
while (i<=DimMax) and (rx[i]=0) do Inc(i);
NrZero:=i-1
end;
function Test:Boolean;
{ returneaza true daca numerele n, m formeaza o }
{ pereche distinsa (reprezentarea Fibonacci a }
{ lui n are un numar par de zerouri, iar }
{ reprezentarea Fibonacci a lui m se obtine }
{ adaugand un zero la reprezentarea lui n) }
var n0,m0,i:Indice;
egal:Boolean;
begin
Test:=false;
n0:=NrZero(rn); m0:=NrZero(rm);
if (n0 mod 2=0) and (m0=n0+1)
then
begin
i:=n0+1; egal:=true;
while (i<=DimMax) and egal do
begin
if rn[i]<>rm[i+1] then egal:=false;
Inc(i)
end;
Test:=egal
end
end;
function DeterminaTermen(var rx: ReprezentareF):
comp;
{ returneaza numarul natural care formeaza o }
{ pereche distinsa cu numarul cu }
{ reprezentarea rx }
var x0,i:Indice; v:comp;
begin
v:=0;
x0:=NrZero(rx);
if x0 mod 2=0
then for i:=1 to DimMax do v:=v+s[i+1]*rx[i]
else for i:=2 to DimMax do v:=v+s[i-1]*rx[i];
DeterminaTermen:=v
end;
procedure DeterminaPereche(d:comp; var a,b:comp);
{ determina unica pereche distinsa (a,b), }
{ astfel incat b-a=d }
var rd:ReprezentareF;
d0,i,m:Indice;
begin
Reprezinta(d,rd);
rd[DimMax+1]:=0; rd[DimMax+2]:=0;
d0:=NrZero(rd);
a:=0; b:=0;
if d0 mod 2=1
then
for i:=1 to DimMax do
begin
a:=a+rd[i]*s[i+1];
b:=b+rd[i]*s[i+2]
end
else
begin
m:=d0 div 2;
for i:=0 to m do
begin
a:=a+s[2*i+1];
b:=b+s[2*i+2]
end;
for i:=2*m+2 to DimMax do
begin
a:=a+rd[i]*s[i+1];
b:=b+rd[i]*s[i+2]
end
end
end;
Begin
Citire;
GenerareSirFibonacci;
Reprezinta(n,rn);
Reprezinta(m,rm);
Write('fisier iesire='); Readln(nume);
Assign(fout,nume); Rewrite(fout);
if Test
then
Writeln(fout,
'Jucatorul 1 este in situatie de pierdere')
else
begin
Writeln(fout,'Jucatorul 1 are strategie de
castig');
if (n=m) or (n=0)
then
begin
Writeln(fout,n:20:0,m:20:0);
Writeln(fout,n-n:20:0,' ',m-m:20:0)
end
else
begin { 0<n<m }
p:=DeterminaTermen(rn);
if m>p
then
begin
Writeln(fout,0,' ',m-p:20:0);
Writeln(fout,n:20:0,p:20:0)
end
else
begin
DeterminaPereche(m-n,a,b);
Writeln(fout,n-a:20:0,m-b:20:0);
Writeln(fout,a:20:0,b:20:0)
end
end
end;
Close(fout)
End.