{ File: tabula1.pas }

{ Scopo: utilizzo di procedure e funzioni }

program Tabula;
{ Legge
    - un estremo inferiore
    - un estremo superiore
    - un passo
  e, per una funzione F definita al suo interno,
  (a) tabula la funzione F tra l'estremo inferiore e quello superiore con il
      passo specificato
  (b) calcola il minimo e il massimo tra i valori che la funzione assume
      nei punti di tabulazione
  (c) stampa un istogramma della funzione, scalato su 70 colonne dello
      schermo rispetto ai valori minimo e massimo calcolati al punto (b)

  Versione che NON utilizza parametri per variabile.
}

const
  ColIstogramma = 70;

var
  inferiore,        { estremo inferiore dell'intervallo di tabulazione }
  superiore,        { estremo superiore dell'intervallo di tabulazione }
  passo,            { passo }
  min,              { minimo  della funzione nell'intervallo di tabulazione }
  max       : real; { massimo della funzione nell'intervallo di tabulazione }


  function F (x : real) : real;
  begin
    F := 3.0 * x * x - 4.0 * x + 5.0
  end; { F }


  procedure Tabulazione (inf, sup, passo : real);
  var
    x : real;      { punto corrente }
    j : integer;   { indice del ciclo usato per la tabulazione }
  begin
    x := inf;
    writeln('x':8, 'F(x)':10);
    for j := 0 to trunc((sup - inf) / passo) do
    begin
      writeln(x:8:3, F(x):10:3);
      x := x + passo
    end
  end; { Tabulazione }


  function Massimo (inf, sup, passo : real) : real;
  var
    x      : real;      { punto corrente }
    j      : integer;   { indice del ciclo usato per la tabulazione }
    max,                { massimo corrente }
    valore : real;      { valore della funzione nel punto corrente }
  begin
    x := inf;
    max := F(inf);
    for j := 0 to trunc((sup - inf) / passo) do
    begin
      valore := F(x);
      if valore > max then
        max := valore;
      x := x + passo
    end;
    Massimo := max
  end; { Massimo }


  function Minimo (inf, sup, passo : real) : real;
  var
    x    : real;        { puntocorrente }
    j    : integer;     { indice del ciclo usato per la tabulazione }
    min,                { minimo corrente }
    valore : real;      { valore della funzione nel punto corrente }
  begin
    x := inf;
    min := F(inf);
    for j := 0 to trunc((sup - inf) / passo) do
    begin
      valore := F(x);
      if valore < min then
        min := valore;
      x := x + passo
    end;
    Minimo := min
  end; { Minimo }


  procedure Istogramma (inf, sup, passo, minimo, massimo : real);
  var
    x,              { valore corrente }
    val : real;     { valore della funzione corrente }
    j, k : integer;
  begin
    x := inf;
    writeln(minimo:12:3, massimo:67:3);
    for j := 0 to trunc((sup - inf) / passo) do
    begin
      val := F(x);
      write(x:8:3, ' ');
      for k := 1 to round((val-minimo)*ColIstogramma / (massimo-minimo)) do
        write('*');
      x := x + passo;
      writeln
    end
  end; { Istogramma }


begin { Tabula }
  writeln('Estremo inferiore, estremo superiore e passo della funzione ?');
  readln(inferiore, superiore, passo);
  writeln;
  writeln('TABULAZIONE DELLA FUNZIONE:');
  Tabulazione(inferiore, superiore, passo);
  writeln;
  min := Minimo(inferiore, superiore, passo);
  writeln('Minimo:  ', min:8:4);
  max := Massimo(inferiore, superiore, passo);
  writeln('Massimo: ', max:8:4);
  writeln;
  writeln('ISTOGRAMMA DELLA FUNZIONE:');
  Istogramma(inferiore, superiore, passo, min, max)
end. { Tabula }