{ File: palin2.pas }

{ Scopo: array di caratteri, procedure con parametri di tipo array }

program Palindrome2;

{ Data  in input una sequenza di al piu' 20 lettere (maiuscole o minuscole)
  terminata da '.', la memorizza in un array di caratteri, verifica se essa e`
  palindroma (non distinguendo tra maiuscole e minuscole) e stampa un
  messaggio conseguente.

  Si suppone che l'input sia corretto rispetto alla specifica
  (insomma non diamo piu' di 20 lettere ...). }

{
  ALGORITMO
  1) leggere l'input e metterlo in FRASE
  2) convertire tutti i caratteri minuscoli di FRASE nei corrisp. maiuscoli
  3) verificare la palindromia di FRASE (fino a ULT) e assegnare PALIN
     opportunamente
  4) stampare il messaggio sulla palindromia

  Usiamo:
    una procedura LEGGIFRASE per leggere la frase di input,
    una procedura VERIFICA per verificare la palindromia,
    una procedura MIN_TO_MAIUSC per convertire un carattere minuscolo
    nel corrispondente minuscolo.
  }

const
  N = 20;

type
  TipoFrase = array [1..N] of char;

var
  frase : TipoFrase;
  palin : boolean;
  ult   : integer;   { ult e' l'indice dell'ultimo carattere significativo
                       memorizzato nell'array }


  procedure LeggiFrase (var f: TipoFrase; var u: integer);
  { Legge da input una sequenza di lettere, terminata da '.' e
    le memorizza in F, assegnando U con l'indice dell'ultimo carattere
    significativo letto:
    modifica i parametri attuali della chiamata --> passaggio per variabile
    }

  var
    i : integer;
    c : char;     { per leggere i caratteri da assegnare a F }

  begin { LeggiFrase }
    i := 1;
    read(c);

    while c <> '.' do
    begin
      f[i] := c;
      i := i+1;
      read(c);
    end;

    u := i-1;
    readln    { vedere in PALIN1.PAS perche' ... }
  end; { LeggiFrase }

  procedure VerificaPalindromia (f: TipoFrase; u: integer; var p: boolean);
  { Assegna a P TRUE o FALSE a seconda della palindromia della sequenza dei
    caratteri 1..U in F.
    NB: solo il parametro attuale connesso a P va cambiato
        --> solo P per variabile }

  var
    i, j : integer;    { per scandire la frase }

  begin { VerificaPalindromia }
    i := 1;
    j := u;
    p := TRUE;

    while p and (i < j) do
    begin
      if f[i] <> f[j] then p := FALSE;
      { N.B. Non c'e` il ramo else }
      i := i+1;
      j := j-1
    end;
  end; { VerificaPalindromia }

  procedure MinToMaiusc (var v: TipoFrase; u: integer);
  { Converte in maiuscolo i caratteri minuscoli compresi tra gli indici
    1 e U in V. }
  var
    i : integer;  {per scandire i caratteri della frase}
  begin
    for i := 1 to U do                { per ogni carattere significativo in V }
      if ('a' <= V[i]) and (V[i] <= 'z') then  { se il carattere e' minuscolo }
        V[i] := chr(ord(V[i])-ord('a')+ord('A')); { assegnalo con il
                                                    corrispondente maiuscolo }
  end; { MinToMaiusc }

begin { Palindrome2 }
  LeggiFrase(frase, ult);
  MinToMaiusc(frase, ult);
  VerificaPalindromia(frase, ult, palin);

  { ora in PALIn c'e' TRUE o FALSE ... }
  if palin then
    writeln(' ... e'' palindroma')
  else
    writeln(' ... non e'' palindroma');

end. { Palindrome2 }