{************************************************************************* 
  This is a program that reads a block of text into an array
  of pointers.  The program then enciphers the text by reading
  down the array from left to right instead of across the array
  from top to bottom.  The width of the array created can be
  varied by changing the constant arraywidth.
  for example the message 'meet me at seven' with an array width
  of 4 becomes 'm aeemtvee et sn', but with an arraywidth of 3
  becomes 'mtetene   v emase '. 
 ************************************************************************** }

program deciphskytale(input,output,infile,outfile);


const
  arraywidth = 4;
type
  nodepoint = ^nodetype;
  nodetype = record
               next:nodepoint;
               ch:array[1..arraywidth] of char;
             end;
var
  firstptr,currentptr:nodepoint;
  ch:char;
  infile:text;
  outfile:text;
  letters:set of char;
  i:integer;
  size:integer;


begin
                       {  These are all the characters that you do not}
                       {   want the program to ignore in message.  }
  letters:=['A'..'Z','a'..'z','0'..'9',',','.','?',' '];

  new(firstptr);       {  Firstptr is a pointer that always points     }
                      {    to the top left of the array  }

  currentptr:=firstptr;   {  Initially currentptr points to firstptr  }

  reset(infile);       {  Message is the text file to be encoded  }

  i:=0;                 {  i is a counter that records the horizontal  }
                     {      position of currentptr  }

  while not eof(infile) do
  begin
    read(infile,ch);
    if ch in letters then
    begin
      i:=i+1;
    end;
  end;

  if (i mod arraywidth) <> 0 then
    size:=trunc(i/arraywidth) + 1
  else
    size:=trunc(i/arraywidth);

  for i := 1 to size do
  begin
    new(currentptr^.next);
    currentptr:=currentptr^.next;
  end;

  currentptr^.next:=nil;
  currentptr:=firstptr;
  reset(infile);
  i:=1;

  while not eof(infile) do
  begin
    read(infile,ch);
    if ch in letters then
    begin
      currentptr^.ch[i]:=ch;
      currentptr:=currentptr^.next;
      if currentptr^.next=nil then
      begin
        currentptr:=firstptr;
        i:=i+1
      end;
    end;
  end;

                          {  Message has been read into the array      }
                          {    and is no longer needed.  }

  currentptr:=firstptr;     {  Set currentptr to beginning of array.  }
  i:=0;
  rewrite(outfile);

  while currentptr^.next <> nil do
  begin
    for i:= 1 to arraywidth do
    begin
      write(outfile,currentptr^.ch[i]);
    end;
    currentptr:=currentptr^.next;
  end;
end.

