Cod sursa(job #71633)

Utilizator mlazariLazari Mihai mlazari Data 11 iulie 2007 01:09:34
Problema Bool Scor 80
Compilator fpc Status done
Runda Arhiva de probleme Marime 4.83 kb
Program Bool;
const fals=0;
      adevar=1;
      nu=2;
      si=3;
      sau=4;
      ParOpen=5;
      ParClose=6;

var V : array[65..90] of integer;
    Change : array[1..100] of char;
    answer : array[1..100] of integer;
    E,Ev : array[0..1001] of integer;
    nE,nEv,N : integer;

procedure Citeste;
var Intrare : text;
    i : integer;
    ch : char;
    tonext : boolean;
begin
  assign(Intrare,'bool.in');
  reset(Intrare);
  nE:=1;
  E[1]:=ParOpen;
  tonext:=true;
  while not eoln(Intrare) do
   begin
     if tonext then read(Intrare,ch);
     tonext:=true;
     if ch<>' ' then nE:=nE+1 else continue;
     case ch of
      '(': E[nE]:=ParOpen;
      ')': E[nE]:=ParClose;
      'A': if eoln(Intrare) then E[nE]:=65
            else
             begin
               read(Intrare,ch);
               if ord(ch)<65 then
                begin
                  E[nE]:=65;
                  if ch=')' then tonext:=false;
                end
                else
                 begin
                   read(Intrare,ch);
                   E[nE]:=si;
                 end;
             end;
      'N': if eoln(Intrare) then E[nE]:=78
            else
             begin
               read(Intrare,ch);
               if ord(ch)<65 then
                begin
                  E[nE]:=78;
                  if ch=')' then tonext:=false;
                end
                else
                 begin
                   read(Intrare,ch);
                   E[nE]:=nu;
                 end;
             end;
      'O': if eoln(Intrare) then E[nE]:=79
            else
             begin
               read(Intrare,ch);
               if ord(ch)<65 then
                begin
                  E[nE]:=65;
                  if ch=')' then tonext:=false;
                end
                else E[nE]:=sau;
             end;
      'F': if eoln(Intrare) then E[nE]:=70
            else
             begin
               read(Intrare,ch);
               if ord(ch)<65 then
                begin
                  E[nE]:=70;
                  if ch=')' then tonext:=false;
                end
                else
                 begin
                   read(Intrare,ch);
                   read(Intrare,ch);
                   read(Intrare,ch);
                   E[nE]:=fals;
                 end;
             end;
      'T': if eoln(Intrare) then E[nE]:=84
            else
             begin
               read(Intrare,ch);
               if ord(ch)<65 then
                begin
                  E[nE]:=84;
                  if ch=')' then tonext:=false;
                end
                else
                 begin
                   read(Intrare,ch);
                   read(Intrare,ch);
                   E[nE]:=adevar;
                 end;
             end;
      else E[nE]:=ord(ch);
     end;
   end;
  nE:=nE+1;
  E[nE]:=ParClose;
{  readln(Intrare);}
  readln(Intrare,N);
  for i:=1 to N do read(Intrare,Change[i]);
  close(Intrare);
end;

function _not(a : integer) : integer;
begin
  if a=0 then _not:=1 else _not:=0;
end;

function _or(a,b : integer) : integer;
begin
  if a+b<>0 then _or:=1 else _or:=0;
end;

function _and(a,b : integer) : integer;
begin
  _and:=a*b;
end;

procedure Evaluate;
var r : integer;
begin
  case Ev[nEv] of
            nu: if Ev[nEv-1]=nu then nEv:=nEv-2;
   fals,adevar: if Ev[nEv-1]=nu then
                 begin
                   Ev[nEv-1]:=_not(Ev[nEv]);
                   nEv:=nEv-1;
                   Evaluate;
                 end
                 else
                  if Ev[nEv-1]=si then
                   begin
                     Ev[nEv-2]:=_and(Ev[nEv-2],Ev[nEv]);
                     nEv:=nEv-2;
                   end;
      ParClose: begin
                  nEv:=nEv-1;
                  r:=Ev[nEv];
                  while Ev[nEv-1]<>ParOpen do
                   begin
                     r:=_or(r,Ev[nEv-2]);
                     nEv:=nEv-2;
                   end;
                  nEv:=nEv-1;
                  Ev[nEv]:=r;
                  Evaluate;
                end;
  end;
end;

function Value : integer;
var i : integer;
begin
  nEv:=0;
  for i:=1 to nE do
   begin
     nEv:=nEv+1;
     if E[i]<65 then Ev[nEv]:=E[i] else Ev[nEv]:=V[E[i]];
     if not(E[i] in [ParOpen,si,sau]) then Evaluate;
   end;
  Value:=Ev[1];
end;

procedure Calculeaza;
var i : integer;
begin
  Ev[0]:=-1;
  for i:=65 to 90 do V[i]:=0;
  for i:=1 to N do
   begin
     V[ord(change[i])]:=_not(V[ord(change[i])]);
     answer[i]:=Value;
   end;
end;

procedure Scrie;
var Iesire : text;
    i : integer;
begin
  assign(Iesire,'bool.out');
  rewrite(Iesire);
  for i:=1 to N do write(Iesire,answer[i]);
  close(Iesire);
end;

begin
  Citeste;
  Calculeaza;
  Scrie;
end.