program coupes;

{uses crt;}

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; { visu }



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; { init_tab }

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; { question1 }


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; { question2 }


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; { palindrome }


function trouve_un(t : table;lg:integer):boolean;
{existe-t-il un palindrome de longueur lg ?}
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);
{nb stocke le nombre, cpt l'indice de début du deuxième}
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;


{si pas de palindrome de longueur 13, ni de longueur 12}
{il n'y en a pas de plus grand}

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 {c'est fini}
      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; { plus_long_palindrome }

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; { plus_longue_nulle }


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;

{exactement les memes idees}

function trouve_une_equilibree(t : table;lg:integer):boolean;
{existe-t-il une coupe equilibree de longueur lg ?}
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);
{nb stocke le nombre, cpt l'indice de début du deuxième}
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;

{si pas d'équilibrée de longueur 13, ni de longueur 12}
{il n'y en a pas de plus grande}

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 {c'est fini}
      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; {plus_longue_equilibree}


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.