#!/usr/bin/perl -s

=head1 Detector de línguas

  opções: -v  (verbose)
          -jt (just terminations)

  . detecta 12 línguas
    - por Marta Henriques Jacinto
    - para Processamento de Linguagens, Mestrado em Informática da UMinho
    - no 1º Semestre de 1998/1999

=cut

%todo=(letra=>1,par=>1,term=>1);
if($jt){$todo{letra}=0; $todo{par}=0}

### DEFINIÇÕES ###

# definição de todos os caracteres e inicialização dos respectivos contadores a zero

@car = ('a'..'z','á', 'é', 'í', 'ó', 'ú', 'à', 'è', 'ã', 'õ', 'ä', 'ë', 'ï', 'ö', 'ü', 'å', 'ß', 'ç', 'ñ', 'ý', 'æ', 'ø', 'â', 'ê', 'î', 'ô', 'û' ) ;
for $a (@car) { $cl{$a}=0; }

# definição de todos os pares e inicialização dos respectivos contadores a zero
for $a (@car) { for $b (@car) { $cp{$a.$b}=0; } }

@valor = ('letra', 'par', 'term');

### VALORES TEÓRICOS... elementos significativos ###

%lingua = (
alemanha => { 
  letra =>{'a'=>0.0471, 'e'=>0.162, 'i'=>0.0713, 'n'=>0.104, 'r'=>0.0684, 
    's'=>0.056, 't'=>0.0498, 'ä'=>0.00705, 'ö'=>0.00457, 'ü'=>0.00526,
    'ß'=>0.00152 },
  par => {'ch'=>0.027, 'de'=>0.0254, 'ei'=>0.0187, 'en'=>0.0465, 'er'=>0.036,
    'fü'=>0.00376, 'hl'=>0.00311, 'ie'=>0.0196, 'in'=>0.0187, 'wä'=>0.0023,
    'äh'=>0.0023, 'än'=>0.00213, 'üh'=>0.00278},
  term => {'che'=>0.0233, 'den'=>0.0349, 'der'=>0.0448, 'die'=>0.0305,
    'hen'=>0.0224, 'nen'=>0.0251, 'ten'=>0.0305} },

catalunha => { 
 letra =>{'a'=>0.0897, 'e'=>0.113, 'i'=>0.059, 'l'=>0.0504, 'n'=>0.0454,
    'o'=>0.0402, 'r'=>0.0607, 's'=>0.0692, 't'=>0.052, 'é'=>0.00276,
    'í'=>0.00161, 'ó'=>0.00731, 'à'=>0.00431, 'è'=>0.00231 },
  par => {'de'=>0.0259, 'el'=>0.0153, 'es'=>0.0355, 'ió'=>0.00832,
    're'=>0.0169, 'rà'=>0.00332, 'tè'=>0.00166, 'èg'=>0.00166},
  term => {'a'=>0.022, 'ció'=>0.0224, 'de'=>0.0687, 'el'=>0.0195,
    'els'=>0.0206, 'en'=>0.0195, 'i'=>0.0163, 'l'=>0.0264, 'la'=>0.0333,
    'les'=>0.027, 'que'=>0.0181}, },

dinamarca => {
  letra =>{'a'=>0.0529, 'd'=>0.0558, 'e'=>0.143, 'i'=>0.0537, 'n'=>0.0765,
    'r'=>0.08, 's'=>0.0584, 't'=>0.0665, 'å'=>0.0076, 'æ'=>0.0108, 'ø'=>0.01},
  par => {'de'=>0.0353, 'en'=>0.0348, 'er'=>0.035, 'et'=>0.0175, 'mæ'=>0.00303,
    'or'=>0.0171, 'på'=>0.0034, 'rå'=>0.00167, 'ræ'=>0.00214, 'sø'=>0.00408,
    'æl'=>0.00397, 'æn'=>0.00256, 'ær'=>.00193, 'øg'=>0.00413, 'ør'=>0.00575},
  term => {'den'=>0.0243, 'der'=>0.0302, 'i'=>0.0261, 'af'=>0.0386,
    'at'=>0.0263, 'for'=>0.0189, 'ing'=>0.0298, 'og'=>0.0184}, },

espanha => {
  letra =>{'a'=>0.0859, 'c'=>0.0422, 'd'=>0.0476, 'e'=>0.104, 'i'=>0.0578,
    'l'=>0.0416,'n'=>0.0539, 'o'=>0.063, 'r'=>0.0509, 's'=>0.0569, 'á'=>0.00334,
    'é'=>0.00172, 'í'=>0.00382, 'ó'=>0.00641, 'ú'=>0.000824, 'ñ'=>0.0012 },
  par => {'ci'=>0.0166, 'de'=>0.0326, 'en'=>0.0183, 'er'=>0.0149, 'es'=>0.0209,
    'ió'=>0.007, 'la'=>0.0173, 'rá'=>0.00252, 'íc'=>0.00178},
  term => {'a'=>0.0166, 'de'=>0.0863, 'en'=>0.0187, 'la'=>0.0407,
    'que'=>0.0178, 'ión'=>0.0284, 'las'=>0.0162, 'y'=>0.022}, },

finlandia => {
  letra =>{'a'=>0.106, 'e'=>0.0746, 'i'=>0.0836, 'k'=>0.0544, 'n'=>0.0708,
    'o'=>0.0502,'s'=>0.0647,'t'=>0.0797, 'u'=>0.0464, 'ä'=>0.032, 'ö'=>0.00405},
  par => {'an'=>0.0173, 'en'=>0.0247, 'is'=>0.017, 'kä'=>0.00285,
    'lä'=>0.00236, 'mä'=>0.00236, 'sä'=>0.00248, 'ta'=>0.0198, 'uu'=>0.00538,
    'vä'=>0.0033, 'yö'=>0.00216, 'äi'=>0.00248, 'än'=>0.00318, 'är'=>0.00204,
    'ät'=>0.00276, 'ää'=>0.00643},
  term => {'den'=>0.0243, 'nen'=>0.0209, 'aan'=>0.0257, 'een'=>0.0274,
    'ja'=>0.0396, 'on'=>0.0279, 'ssa'=>0.0285, 'sta'=>0.0209}, },

franca => {
  letra =>{'a'=>0.0551, 'e'=>0.107, 'i'=>0.0554, 'l'=>0.0403, 'n'=>0.0574,
    'o'=>0.0441, 'r'=>0.0576, 's'=>0.0605, 't'=>0.0529, 'u'=>0.0389, 'é'=>0.019,
    'à'=>0.00263, 'è'=>0.00256, 'ê'=>0.000977 },
  par => {'de'=>0.0194, 'dé'=>0.00224, 'en'=>0.0176, 'er'=>0.0144,
    'es'=>0.0241, 'le'=>0.0193, 'nt'=>0.0148, 'né'=>0.00186, 'on'=>0.0206,
    'pé'=>0.00154, 're'=>0.0144, 'ur'=>0.0138, 'éc'=>0.00217, 'ée'=>0.00229,
    'ét'=>0.00163},
  term => {'de'=>0.0419, 'en'=>0.0216, 'l'=>0.0236, 'la'=>0.0236,
    'les'=>0.0285, 'des'=>0.0211, 'ent'=>0.0155, 'et'=>0.0168, 'ion'=>0.0224,
    'le'=>0.0193}, },

holanda => {
  letra =>{'a'=>0.0685, 'd'=>0.0513, 'e'=>0.17, 'i'=>0.0572, 'n'=>0.0895,
    'o'=>0.0458, 'r'=>0.0582, 't'=>0.0599 },
  par => {'an'=>0.0279, 'de'=>0.034, 'en'=>0.0448, 'er'=>0.0271, 'ge'=>0.0174,
    'in'=>0.0176, 'jk'=>0.00184, 'te'=>0.0168},
  term => {'den'=>0.0242, 'de'=>0.074, 'ing'=>0.0203, 'een'=>0.0208,
    'het'=>0.0295, 'van'=>0.0428}, },

hungria => {
  letra =>{'a'=>0.0955, 'e'=>0.0846, 'l'=>0.0675, 's'=>0.0739, 't'=>0.0754,
    'z'=>0.0489, 'á'=>0.0498, 'é'=>0.0415, 'í'=>0.00597, 'ó'=>0.0115, 
    'ú'=>0.002,'õ'=>0.002,'ö'=>0.0163,'ü'=>0.00683,'ô'=>0.00819,'û'=>0.00432 },
  par => {'dá'=>0.00232, 'el'=>0.0225, 'já'=>0.00209, 'kö'=>0.008,
    'lá'=>0.00326, 'lô'=>0.00314, 'pv'=>0.00249, 'sz'=>0.0225, 'sá'=>0.0107,
    'sé'=>0.0074, 'tö'=>0.0041, 'vá'=>0.00319, 'yû'=>0.00378, 'zt'=>0.00852,
    'zá'=>0.00828, 'zó'=>0.00235, 'ág'=>0.0117, 'ál'=>0.00751, 'án'=>0.00838,
    'ár'=>0.0103, 'ás'=>0.00974, 'át'=>0.00241, 'ég'=>0.0056, 'ép'=>0.00308,
    'ét'=>0.0033, 'év'=>0.00215, 'ól'=>0.00402, 'ök'=>0.00287, 'öz'=>0.00483,
    'ûl'=>0.0038, 'ül'=>0.00419},
  term => {'a'=>0.105, 'az'=>0.0473, 'ság'=>0.0201, 'és'=>0.0347}, },

inglaterra => {
  letra =>{'a'=>0.0763, 'e'=>0.13, 'i'=>0.079, 'n'=>0.0812, 'o'=>0.078,
    'r'=>0.07, 's'=>0.0656, 't'=>0.0887 },
  par => {'an'=>0.0214, 'by'=>0.00206, 'er'=>0.0208, 'he'=>0.0237,
    'on'=>0.0203, 'th'=>0.0286, 'wh'=>0.00247},
  term => {'ing'=>0.0279, 'ion'=>0.0265, 'and'=>0.0197, 'of'=>0.0318,
    'the'=>0.0733, 'to'=>0.0221}, },

italia => {
  letra =>{'a'=>0.0975, 'e'=>0.119, 'i'=>0.116, 'l'=>0.0566, 'n'=>0.0755,
    'o'=>0.0823, 'r'=>0.0602, 's'=>0.0507, 't'=>0.0679, 'à'=>0.00226,
    'è'=>0.00226},
  par => {'di'=>0.0184, 'en'=>0.0194, 'in'=>0.0153, 'on'=>0.0231,
    're'=>0.0181},
  term => {'che'=>0.0308, 'di'=>0.0504, 'e'=>0.0207, 'in'=>0.0225,
    'nte'=>0.0223, 'one'=>0.0279}, },

portugal => {
  letra =>{'a'=>0.133, 'd'=>0.0545, 'e'=>0.122, 'i'=>0.0642, 'o'=>0.111,
    'r'=>0.0657, 's'=>0.0756, 't'=>0.0524, 'á'=>0.00662, 'é'=>0.00411,
    'í'=>0.00274, 'ó'=>0.00205, 'à'=>0.00145, 'ã'=>0.0108, 'õ'=>0.00165,
    'ç'=>0.00764, 'â'=>0.000818, 'ê'=>0.00181},
  par => {'aç'=>0.00423, 'de'=>0.027, 'es'=>0.0208, 'nã'=>0.00365,
    'os'=>0.0185, 'ár'=>0.00271, 'ão'=>0.0134, 'çã'=>0.00472, 'õe'=>0.00208},
  term => {'a'=>0.0436, 'de'=>0.0554, 'que'=>0.0221, 'e'=>0.0226, 'o'=>0.041},},

suecia => {
  letra =>{'a'=>0.087, 'e'=>0.106, 'f'=>0.0637, 'n'=>0.0984, 'r'=>0.0793,
     's'=>0.0622, 't'=>0.0917, 'ä'=>0.018, 'ö'=>0.014, 'å'=>0.014},
  par => {'de'=>0.0307, 'en'=>0.0329, 'er'=>0.0227, 'et'=>0.0185,
    'fö'=>0.00941, 'in'=>0.0215, 'lä'=>0.00245, 'på'=>0.00212, 'rä'=>0.00381,
    'rå'=>0.00332, 'vä'=>0.00337, 'än'=>0.00593, 'är'=>0.00648, 'åd'=>0.00278,
    'ån'=>0.00376, 'öv'=>0.00202},
  term => {'den'=>0.0356, 'i'=>0.0494, 'att'=>0.0244, 'det'=>0.0259,
    'och'=>0.0374, 'rna'=>0.0209}, },
);

@paises = keys(%lingua);
@terminus = (map { keys %{$lingua{$_}{term}} } @paises);
@terminus{@terminus} = @terminus; @terminus = keys %terminus;
@caract = (map { keys %{$lingua{$_}{letra}} } @paises);
@caract{@caract} = @caract; @caract = keys %caract;
@pares = (map { keys %{$lingua{$_}{par}} } @paises);
@pares{@pares} = @pares; @pares = keys %pares;

### OCORRÊNCIAS DOS ELEMENTOS NO TEXTO ###

undef $/ ;

while (<>){
	$_=lc($_);
	s/[\015\.\,\;\:\!\?]/ /g;	# substituir qualquer elemento de
	s/[\(\)\^\"\/\\\']/ /g;		# pontuação do texto que está a ser
	s/[\*\+\- \ -\=]/ /g;		# analisado
	s/[\$\#\&\%]/ /g;
	s/[\{\}\[\]\<\>]/ /g;
	s/[0-9]/ /g; 

        $padraocl = join('|',keys(%cl));
        if($todo{letra}){
          s/$padraocl/contal($&)/gei;	# ocorrências das letras
        }

        if($todo{par}){
          $padraocp = join('|',keys(%cp));
          s/$padraocp/contap($&)/gei;	# ocorrências dos pares
        }

        chomp;
        if($todo{term}){
          @pal = m/((?:$padraocl)+)/g; 	# ocorrências das terminações
          for $a (@pal){
	     contat($a) unless $a eq "";
          }
        }
}

###       CÁLCULO DOS VALORES QUE DEVEM MULTIPLICAR OS TEÓRICOS       ###
### percentagens dos elementos e somas das percentagens dos elementos ###
### significativos para cada língua...				      ###


# caracteres
if($todo{letra}){
  for $l (@caract) {
    $percl{$l}=100*$cl{$l}/$totalL;
    for(@paises){ $val{$_}+=$percl{$l} if $lingua{$_}{letra}{$l}}
  }
}

# pares
if($todo{par}){
  for $p (@pares) {
    $percp{$p}=100*$cp{$p}/$totalP;
    for(@paises){ $val{$_}+=$percp{$p} if $lingua{$_}{par}{$p}}
  }
}

# terminações
if($todo{term}){
  for $t (@terminus) {
    $perct{$t}=100*$ct{$t}/$totalT;
    for(@paises){ $val{$_}+=$perct{$t} if $lingua{$_}{term}{$t}}
  }
}

### CÁLCULO DO TOTAL - peso de ser ou não essa língua - PARA CADA LÍNGUA ###

# caracteres
if($todo{letra}){
  for $l (@caract) {
    for(@paises){ $total{$_}+=$percl{$l}*$val{$_}*$lingua{$_}{letra}{$l};}
  }
}

# pares
if($todo{par}){
  for $p (@pares) {
    for(@paises){ $total{$_}+=$percp{$p}*$val{$_}*$lingua{$_}{par}{$p};}
  }
}

# terminações
if($todo{term}){
  for $t (@terminus) {
    for(@paises){ $total{$_}+=$perct{$t}*$val{$_}*$lingua{$_}{term}{$t};}
  }
}

### RESULTADOS ###

@valores = sort{$total{$b} <=> $total{$a}} keys (%total);
# Impressão dos resultados

if($v){
   for $p (@valores) { print lingua($p), " $total{$p}\n"; }}
elsif($marta) {
   print "\n\nO texto que introduziu é provavelmente:\n";
   print "			-> ", lingua($valores[0]),"\n";
   print "\nComo segunda opção deve considerar:\n";
   print "			-> ", lingua($valores[1]),"\n";}
else { print "$valores[0]\n";}

### FUNÇÕES AUXILIARES ### 

# conta letras
sub contal{
        my $l = shift;
        $cl{$l}++;
        $totalL++;
        $l;
}     

# conta pares de letras
sub contap{
        my $p = shift;
        $cp{$p}++;
        $totalP++;
        $p;
}     

# conta terminações
sub contat{
        my $p = shift;
	my $t = substr($p,-3);
        $ct{$t}++;
	$totalT++;
	$p;
}

# transforma o nome do país na língua que se fala nesse país
sub lingua{
	my $li = shift;
	if ($li eq 'alemanha') {$r='alemão';}
	elsif ($li eq 'catalunha') {$r='catalão';}
	elsif ($li eq 'dinamarca') {$r='dinamarquês';}
	elsif ($li eq 'espanha') {$r='espanhol';}
	elsif ($li eq 'finlandia') {$r='finlandês';}
	elsif ($li eq 'franca') {$r='francês';}
	elsif ($li eq 'holanda') {$r='holandês';}
	elsif ($li eq 'hungria') {$r='húngaro';}
	elsif ($li eq 'inglaterra') {$r='inglês';}
	elsif ($li eq 'italia') {$r='italiano';}
	elsif ($li eq 'portugal') {$r='português';}
	elsif ($li eq 'suecia') {$r='sueco';}
	$r;
}
