Thank you guys,

The code works perfectly with the keyboard (it won't stop which is normal) or when I feed it an input file (it stops fine after a few milliseconds of work). Eof or Eoln doesn't seem to be the issue. I've tried another problem where the input finishes by the "quit" word, and I have the same issue. FYI, I've attached the two tests for problem 100 (test3) and problem 101 (test4).

Has somebody here delivered a successful pascal program to the UVa online judge: http://icpcres.ecs.baylor.edu/onlinejudge/index.php ?

Test problem 100: http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=36

Test problem 101:
http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=37

Best regards,
Thierry,

Mehmet Erol Sanliturk wrote:
On Friday 27 March 2009 08:08:20 pm JoshyFun wrote:
Hello Thierry,
TC>Is there another way recommended for
TC> these contests?

I have none experience on the contest scene, but eof in the stdin
looks nonsense for me when you input data using the keyboard, 'cos
after the first line (readln) the eof is a fact ;)

"eof or empty line" seems to be more logical to me. You should check
how the program works if you feed stdin from a file:

test.exe < file.txt


Additionally :

Between _readln _ and _until eof_ statements , there should be an if statement such as
if not eof
then
begin
      { statements between readln and until eof ... }
end ;


because when EOF is seen those stements should not be executed because there is no valid input at that state .

Thank you very much .

Mehmet Erol Sanliturk

_______________________________________________
Lazarus mailing list
[email protected]
http://www.lazarus.freepascal.org/mailman/listinfo/lazarus



program Test3 (input, output);
// This is a copy from a known solution to check the online judge...
var
  i, j: integer;

function getCL(N: integer): integer;
var k: integer;
begin
  k := 1;
  while N <> 1 do begin
    if odd(N) then N := 3*N + 1
    else N := N div 2;
    k := k + 1;
  end;
  getCL := k;
end;

function getMaxCL(i, j: integer): integer;
var k: integer;
  max, curCL: integer;
begin
  max := 0;
  for k:=i to j do begin
    curCL := getCL(k);
    if curCL > max then max := curCL;
  end;
  getMaxCL := max;
end;

begin
  while not eof(input) do begin
    readln(i, j);
    write(i, ' ', j, ' ');
    if i < j then
      writeln(getMaxCL(i, j))
    else
      writeln(getMaxCL(j, i));
  end;
end.

program Test4(input, output);

(*$MODE OBJFPC*)
uses
  SysUtils;
type
  TBlock = class
    number: integer;
    stack: integer;
    above: TBlock;
  end;

var
  WaitingForCommands: Boolean;
  aCommand: String;
  N : Integer; // blocksize
  table: array[0..25] of TBlock;
  blocks: array[0..25] of TBlock;

//creates a block for each position on the table
procedure InitializeState;
var
  iBlock: integer;
  aBlock: TBlock;
begin
  for iBlock := 0 to N-1 do
  begin
    aBlock := TBlock.Create;
    aBlock.number := iBlock;
    aBlock.stack := iBlock;
    table[iBlock] := aBlock;
    blocks[iBlock] := aBlock;
  end;
end;

//prints the status of the table
procedure PrintState;
var
  iStack: integer;
  aBlock: TBlock;
begin
  for iStack := 0 to N-1 do
  begin
    write(iStack,':');
    aBlock := table[iStack];
    while assigned(aBlock) do
    begin
      write(' ', aBlock.number);
      aBlock := aBlock.above;
    end;
    writeln;
  end;
end;

function IsIllegalMove(block1, block2: integer): Boolean;
begin
  //a move is illegal, if block1 = block2, or
  // if block1 and block2 are in the same pile...
  result := false;

  // a = b
  if block1=block2 then
  begin
    result := true;
    exit;
  end;

  // a and b in same stack
  if (block1>N) or (block2>N) then result := true;
  if result then Exit;
  if blocks[block1].stack = blocks[block2].stack then
    result := true;

end;

procedure RemoveFromStack(aBlock:TBlock);
var
  oldStack : integer;
  lastBlock: TBlock;
begin
  //removing the block from the current stack...
  oldStack := aBlock.Stack;
  lastBlock := table[oldStack];
  if lastBlock = aBlock then
    table[oldStack] := nil
  else
  begin
    while lastBlock.above <> aBlock do
      lastBlock := lastBlock.above;
    lastBlock.above := nil;
  end;
  aBlock.stack := -1;
end;

// puts the block on top of the stack..
procedure PutOnStack(aBlock:TBlock; aStack:integer);
var
  lastBlock: TBlock;
begin

  //putting the block on the new stack
  lastBlock := table[ aStack];
  if not assigned(lastBlock) then
    table[aStack] := aBlock
  else
  begin
    while assigned(lastBlock.above) do
      lastBlock := lastBlock.above;
    lastBlock.above := aBlock;
  end;
  aBlock.stack := aStack;
end;

procedure ResetBlocksAbove(aBlock: integer);
var
  firstBlock: TBlock;
  nextBlock: TBlock;
begin
  firstBlock := blocks[aBlock].above;
  while assigned( firstBlock) do
  begin
    nextBlock := firstBlock.above;
    firstBlock.above := nil;
    PutOnStack(firstBlock, firstBlock.number);
    firstBlock := nextBlock;
  end;
end;

procedure MoveOnto(block1, block2:integer);
begin
  ResetBlocksAbove(block1);
  ResetBlocksAbove(block2);
  RemoveFromStack(blocks[block1]);
  PutOnStack( blocks[block1], blocks[block2].stack);
end;

procedure MoveOver(block1, block2:integer);
begin
  ResetBlocksAbove(block1);
  RemoveFromStack(blocks[block1]);
  PutOnStack( blocks[block1], blocks[block2].stack);
end;

procedure PileOnto(block1, block2:integer);
begin
  ResetBlocksAbove(block2);
  RemoveFromStack(blocks[block1]);
  PutOnStack( blocks[block1], blocks[block2].stack);
end;

procedure PileOver(block1, block2:integer);
begin
  RemoveFromStack(blocks[block1]);
  PutOnStack( blocks[block1], blocks[block2].stack);
end;

//processes each command
procedure ProcessCommand( aCommand:String);
var
  C1, C2, B1, B2 : String;
  p : integer;
  block1, block2 : integer;
begin
  // parse command
  p := pos(' ', aCommand);
  //writeln('p:', p); //DEBUG
  // checking for the quit command
  if (p = 0) and (aCommand = 'quit') then
  begin
    WaitingForCommands := false;
    Exit;
  end;

  // each command is of the format : command1 block1 command2 block2, like:
  // move a onto b
  // move a over b
  // pile a onto b
  // pile a over b
  // C1 B1 C2 B2
  C1 := copy( aCommand, 1, p-1);
  delete(aCommand, 1, p);

  p := pos(' ', aCommand);
  B1 := copy( aCommand, 1, p-1);
  delete(aCommand, 1, p);
  block1 := StrToInt(B1);

  p := pos(' ', aCommand);
  C2 := copy( aCommand, 1, p-1);
  delete(aCommand, 1, p);

  B2 := aCommand;
  block2 := StrToInt(B2);

  If not isIllegalMove(block1, block2) then
  begin
    if C1 = 'move' then
    begin
      if C2 = 'onto' then
        MoveOnto(block1, block2)
      else if C2 = 'over' then
        MoveOver(block1, block2);
    end
    else if C1= 'pile' then
    begin
      if C2 = 'onto' then
        PileOnto(block1, block2)
      else if C2 = 'over' then
        PileOver(block1, block2);
    end;
  end;
end;

// main program read data
begin
  Readln(N);
  //writeln('N :', N); //DEBUG
  InitializeState;
  WaitingForCommands := true;
  while WaitingForCommands do
  begin
    Readln( aCommand);
    ProcessCommand( aCommand);
  end;
  PrintState;
end.

_______________________________________________
Lazarus mailing list
[email protected]
http://www.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to