{ 22/nov/2009 }
{ Testa funcao hash perfeita usando 8 bits 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 byte; 
  TipoChave           = packed array[1..MAXTAMCHAVE] of char;
  TipoConjChaves      = array[0..MAXNUMCHAVES] of TipoChave;
  TipoArranjoVertices = array[Tipor] of TipoValorVertice;
  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 4.22- }
  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;  a: TipoArranjoVertices;
begin
v := 0;
for i := 0 to r - 1 do
  begin
  a[i] := h (Chave, Pesos[i]);
  v := v + g[a[i]];
  end;
  v := v mod r;
  hp := a[v];
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 }


