{ tennis.chk.pas }
{ Checker for the TENNIS problem of BOI 2002 }
{ Ahto Truu }
{ Tested with FPC 1.0.4/GO32V2 }

{$I-}

const
   pos = 'SOLUTION'; { "positive" answer }
   neg = 'NO SOLUTION'; { "negative" answer }
   minn = 2; { min allowed number of players }
   maxn = 1000; { max allowed number of players }

var
{ global data }
   n : integer; { number of players }
   p, pp : array [1..maxn] of integer; { player data }
   g : array [1..maxn, 1..maxn] of boolean; { "game matrix" }
   ok : boolean; { do we have a solution? }
{ temporary variables }
   f : text;
   i, j, k, m : integer;
   x, y : longint;
   s : string;

begin
   if paramcount <> 2 then begin
      writeln('Usage: ', paramstr(0), ' inputfile outputfile');
      halt(1);
   end;

   { load the input data }
   assign(f, paramstr(1)); reset(f);
   if ioresult > 0 then begin
      writeln('Error reading input file ', paramstr(1));
      halt(1);
   end;
   readln(f, n);
   if ioresult > 0 then begin
      writeln('Error reading input file ', paramstr(1));
      halt(1);
   end;
   if (n < minn) or (n > maxn) then begin
      writeln('Invalid number of players ', n);
      halt(1);
   end;
   for i := 1 to n do begin
      readln(f, p[i]);
      if ioresult > 0 then begin
         writeln('Error reading input file ', paramstr(1));
         halt(1);
      end;
      if (p[i] < 1) or (p[i] > n - 1) then begin
         writeln('Invalid number of games ', p[i]);
         halt(1);
      end;
   end;
   close(f);
   if ioresult > 0 then begin
      writeln('Error reading input file ', paramstr(1));
      halt(1);
   end;

   { check whether we have a solvable case }
   for i := 1 to n do
      pp[i] := p[i];
   for i := 1 to n do begin
      k := i;
      for j := i + 1 to n do
         if pp[k] < pp[j] then
            k := j;
      if k > i then begin
         j := pp[i]; pp[i] := pp[k]; pp[k] := j;
      end;
   end;
   ok := true;
   x := 0;
   for i := 1 to n - 1 do begin
      x := x + pp[i];
      y := i * (i - 1);
      for j := i + 1 to n do
         if pp[j] < i then
            y := y + pp[j]
         else
            y := y + i;
      if x > y then
         ok := false;
   end;

   { reset the matrix }
   for i := 1 to n do
      for j := 1 to n do
         g[i, j] := false;

   { load the output data }
   assign(f, paramstr(2)); reset(f);
   if ioresult > 0 then begin
      writeln('Error reading output file ', paramstr(2));
      halt(1);
   end;
   readln(f, s);
   if ioresult > 0 then begin
      writeln('Error reading output file ', paramstr(2));
      halt(1);
   end;
   if ok and (s = pos) or not ok and (s = neg) then begin
      writeln('Answer ', s, ' correct')
   end else begin
      writeln('Answer ', s, ' incorrect');
      halt(1);
   end;
   if ok then
      for i := 1 to n do begin
         if seekeof(f) then begin
            writeln('Premature end of output file');
            halt(1);
         end;
         m := 0; { to suppress a warning }
         for j := 1 to p[i] do begin
            if seekeoln(f) then begin
               writeln('Premature end of line ', i);
               halt(1);
            end;
            read(f, k);
            if ioresult > 0 then begin
               writeln('Error reading output file ', paramstr(2));
               halt(1);
            end;
            if (k < 1) or (k > n) then begin
               writeln('Invalid player number ', k, ' on line ', i);
               halt(1);
            end;
            if (j > 1) and not (k > m) then begin
               writeln('Player numbers ', m, ' and ', k, ' on line ', i);
               halt(1);
            end;
            g[i, k] := true;
            m := k;
         end;
         if not seekeoln(f) then begin
            writeln('Extra data at the end of line ', i);
            halt(1);
         end else if not eoln(f) then begin
            writeln('Warning: extra whitespace at the end of line ', i);
         end;
         readln(f);
         if ioresult > 0 then begin
            writeln('Error reading output file ', paramstr(2));
            halt(1);
         end;
      end;
   if not seekeof(f) then begin
      writeln('Extra data at the end of output file');
      halt(1);
   end else if not eof(f) then begin
      writeln('Warning: extra whitespace at the end of output file');
   end;
   close(f);
   if ioresult > 0 then begin
      writeln('Error reading output file ', paramstr(2));
      halt(1);
   end;

   for i := 1 to n do
      if g[i, i] then begin
         writeln('Player ', i, ' is plays against himself');
         halt(1);
      end;
   for i := 1 to n do
      for j := 1 to n do
         if g[i, j] <> g[j, i] then begin
            writeln('Players ', i, ' and ', j, ' have inconsistent data ');
            halt(1);
         end;
   writeln('All correct');
end.
