{ 30/nov/2009 }
{ Testa funcao hash perfeita usando 4 bytes por entrada de g }
program HashingPerfeito;
const 
  MAXNUMVERTICES = 100000; {--Numero maximo de vertices--}
  MAXNUMARESTAS  = 100000; {--Numero maximo de arestas--}
  MAXR           = 5;
  MAXTAMCHAVE    = 6;      {--Numero maximo de caracteres da chave--}
  MAXNUMCHAVES   = 100000; {--Numero maximo de chaves lidas--}
type
  TipoValorVertice = -1..MAXNUMVERTICES;
  TipoValorAresta  = 0..MAXNUMARESTAS;
  Tipor            = 0..MAXR;
  TipoPesos        = array [1..MAXTAMCHAVE] of integer;
  TipoTodosPesos   = array [Tipor] of Tipopesos;
  Tipog            = array[0..MAXNUMVERTICES] of integer;
  TipoChave        = packed array[1..MAXTAMCHAVE] of char;
  TipoConjChaves   = array[0..MAXNUMCHAVES] of TipoChave;
  TipoIndice       = 0..MAXNUMARESTAS;
var
  M         : TipoValorVertice;
  N         : TipoValorAresta;
  r         : Tipor;
  g         : Tipog; 
  Pesos     : TipoTodosPesos; 
  i, j      : integer;
  ConjChaves: TipoConjChaves;
  NomeArq   : string [100];
  Chave     : TipoChave;
  ArqEntrada: text;

{-- Funcao hash universal apresentada no Programa 5.23 --}
function h (Chave: TipoChave; p: TipoPesos): TipoIndice;
var i, Soma: integer;
begin
  Soma := 0;
  for i := 1 to MAXTAMCHAVE do 
    Soma := Soma + ord(Chave[i]) * p[i];
  h := Soma mod M;
end; { h }

function hp (Chave    : TipoChave; 
             r        : Tipor;
             var Pesos: TipoTodosPesos;
             var g    : Tipog): TipoIndice;
var i, v: integer;
begin
  v := 0;
  for i := 0 to r - 1 do v := v + g[h(Chave, Pesos[i])];
  hp := v mod N;
end; { hp }

begin
  write ('Nome do arquivo com chaves a serem lidas: ');
  readln (NomeArq);
  assign (ArqEntrada, NomeArq);
  reset (ArqEntrada);
  readln (ArqEntrada, N);
  readln (ArqEntrada, M);
  readln (ArqEntrada, r);
  for j := 0 to r - 1 do
    begin
    for i := 1 to MAXTAMCHAVE do read (ArqEntrada, Pesos[j][i]); 
    readln (ArqEntrada);
    end;  
  for i := 0 to M-1 do read (ArqEntrada, g[i]); readln (ArqEntrada);
  readln (Chave);
  while Chave <> 'aaaaaa' do 
    begin
    writeln (hp(Chave, r, Pesos, g));
    readln (Chave);
    end;
  close (ArqEntrada);
end. { hashingperfeito }


