program coupes;
const long_tab = 10000;
type table = array[1..long_tab] of integer;
procedure visu(t : table; i, j:integer);
var k : integer;
begin
write('[');
for k:=i to j-1 do
begin
write(t[k],' ; ')
end;
writeln(t[j],']')
end;
procedure init_tab(var t : table);
var last,i : integer;
begin
last:=13;
for i:=1 to long_tab do
begin
last:=last*last mod 3953;
t[i]:=last mod 2;
end;
end;
procedure question1(t : table);
var cpt, i, indice_dernier : integer;
begin
cpt:=0;indice_dernier:=0;
for i:=1 to long_tab do
if t[i]=1 then
begin
inc(cpt);
indice_dernier:=i;
end;
writeln('nombre de 1 : ', cpt);
writeln('dernier : ',indice_dernier);
end;
procedure question2(t : table);
var cpt, i, indice_deux : integer;
begin
cpt:=0;indice_deux:=0;
for i:=0 to long_tab-6 do
begin
if ((t[i]=t[i+6]) AND (t[i+1]=t[i+5]) AND (t[i+2]=t[i+4])) then
begin
inc(cpt);
if cpt=2 then indice_deux:=i;
end;
end;
writeln('nombre de palindromes de longeur 7 : ', cpt);
writeln('indice du deuxième : ',indice_deux);
end;
function palindrome(t : table;pos,l:integer):boolean;
var fini : boolean;
var i : integer;
begin
i:=0;
fini:=false;
while (not(fini) and (i<((l div 2)))) do
begin
if not(t[pos+i]=t[pos+l-i-1]) then fini:=true;
i:=i+1;
end;
palindrome:=not(fini);
end;
function trouve_un(t : table;lg:integer):boolean;
var trouve : boolean;
var i : integer;
begin
if (lg > long_tab) then trouve_un:=false
else
begin
i:=1;trouve:=false;
while ((i< (long_tab - lg)) and (not(trouve))) do
begin
if palindrome(t,i,lg) then trouve:=true else inc(i);
end;
trouve_un:=trouve;
end;
end;
procedure compte_pos(t : table;lg:integer; var cpt,nb:integer);
var i : integer;
begin
cpt:=0; nb:=0;
for i:=1 to (long_tab - lg) do
begin
if palindrome(t,i,lg) then
begin
inc(nb);
if nb=2 then cpt:=i;
end;
end
end;
procedure plus_long_palindrome(t : table);
var nb, cpt,lg, long_max : integer;
var fini : boolean;
begin
lg:=2;fini:=false;
while ((not(fini)) AND (lg <long_tab)) do
begin
if ((not(trouve_un(t,lg))) AND (not(trouve_un(t,lg+1)))) then
begin
fini:=true;
long_max:=lg-1;
end
else
inc(lg);
end;
compte_pos(t,long_max,cpt,nb);
writeln('longueur :', long_max, ', nombre : ', nb, ', position 2e : ',cpt);
end;
procedure plus_longue_nulle(t : table);
var maxi, pos_maxi, pos_provi, c : integer;
begin
c:=1;maxi:=0;pos_maxi:=0;pos_provi:=1;
while t[c]=1 do inc(c);
pos_provi:=c;
while c<long_tab do
begin
while ((c<long_tab) AND (t[c]=0)) do inc(c);
if (c - pos_provi) > maxi then
begin
maxi:=c - pos_provi;
pos_maxi:=pos_provi;
end;
while ((c<=long_tab) AND (t[c]=1)) do inc(c);
pos_provi:=c;
end;
writeln('taille de la plus grande coupe nulle :', maxi);
writeln('indice ', pos_maxi);
end;
function desequilibre(t : table;pos,lg:integer):integer;
var i,dese : integer;
begin
if lg<1 then dese:=-1212 else
begin
dese:=0;
for i:=0 to lg-1 do
begin
if t[pos+i]=1 then inc(dese) else dec(dese);
end
end;
desequilibre:=dese;
end;
function trouve_une_equilibree(t : table;lg:integer):boolean;
var trouve : boolean;
var i : integer;
begin
if (lg > long_tab) then trouve_une_equilibree:=false
else
begin
i:=1;trouve:=false;
while ((i< (long_tab - lg)) and (not(trouve))) do
begin
if desequilibre(t,i,lg)=0 then trouve:=true else inc(i);
end;
trouve_une_equilibree:=trouve;
end;
end;
procedure compte_pos_equ(t : table;lg:integer; var cpt,nb:integer);
var i : integer;
begin
cpt:=0; nb:=0;
for i:=1 to (long_tab - lg) do
begin
if desequilibre(t,i,lg)=0 then
begin
inc(nb);
if nb=2 then cpt:=i;
end;
end
end;
procedure plus_longue_equilibree(t : table);
var nb, cpt,lg, long_max : integer;
var fini : boolean;
begin
lg:=2;fini:=false;
while ((not(fini)) AND (lg <long_tab)) do
begin
if ((not(trouve_une_equilibree(t,lg))) AND (not(trouve_une_equilibree(t,lg+1)))) then
begin
fini:=true;
long_max:=lg-1;
end
else
inc(lg);
end;
compte_pos_equ(t,long_max,cpt,nb);
writeln('longueur :', long_max, ', nombre : ', nb, ', position 2e : ',cpt);
end;
var T : table;
var cpt,i : integer;
BEGIN
init_tab(T);
writeln('init ok');
readln;
question1(T);
readln;
writeln('coupes de longeur 7');
question2(T);
writeln('verif : t[19..28]');
visu(T,19,28);
write('est-ce que t[20..26] est un palindrome ? ');
writeln(palindrome(T,20,7));
readln;
writeln('plus long palindrome :');
plus_long_palindrome(T);
writeln('verif : t[205..222]');
visu(T,205,222);
readln;
writeln('plus longue coupe nulle :');
plus_longue_nulle(T);
writeln('verif : T[46..55]');
visu(T,46,55);
readln;
writeln('plus grande coupe equilibree :');
plus_longue_equilibree(T);
writeln('verif : nombre de 0 dans T[195..195+131]:');
cpt:=0;
for i:=195 to (195+131) do begin if T[i]=0 then inc(cpt) end;
writeln(cpt);
END.