#! /usr/bin/perl -w
use strict;



############################################################################################
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
#VVV####################################################################################VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV#        D  E  C  L  A  R  A  C  I  O     D  E     V  A  R  I  A  B  L  E  S       #VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV####################################################################################VVV#
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
############################################################################################



my $mrna;                      # Variable singular que conte inicialment tota la sequencia mRNA sencera.
my @mrna;                      # Variable plural amb tota la sequencia mRNA separada per bases.
my $n;                         # Longitud del vector @mrna.
my $llargada;                  # Variable singular amb la llargada per la qual es busquen patrons unics.
my $iden;                      # Variable singular amb la primera linia del fitxer FASTA (identificador).
my @seql;                      # Variable plural, cada component correspon a una linia fitxer FASTA mRNA.
my $patro;                     # Variable singular que conté els patrons generats a cada moment.
my @unic;                      # Variable plural que conte els patrons trobats com a unics al mRNA.
my $contadordepatronsunics;    # Variable singular utilitzada com a index posicions vector @unic.
my $inici;                     # Variable singular per marcar l'inici de cada patro a generar. 
my $i;                         # Variable singular utilitzada com a index.
my $j;                         # Variable singular utilitzada com a index.
my $x;                         # Variable singular utilitzada com a comptador del nombre d'operacions.
my $r;                         # Variable singular utilitzada com a avaluador de cert (1) o fals (0).
my $operacions;                # Variable singular per guardar nombre operacions que retorna la funcio.



############################################################################################
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
#VVV####################################################################################VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV#                   E  N  T  R  A  D  A     D  E     D  A  D  E  S                 #VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV####################################################################################VVV#
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
############################################################################################



##### Comprovacio que s'hagi especificat l'argument d'entrada.

if (scalar(@ARGV) < 1){
    print "correspondenciaexacta.pl: fitxer_mrna\n";
    exit(1);
}


##### Obertura del fitxer de mRNA especificat a l'argument passat al programa (des del shell).
###   El fitxer amb la sequencia del mRNA esta en format FASTA. Per tant, conte una primera linia amb el 
##    simbol '>' seguit d'un identificador, i despres una serie de linies amb la resta de la sequencia.

if (!open(MRNA,"< $ARGV[0]") ) {
    print STDERR "cercasubsequencies.pl: impossible obrir $ARGV[0]\n";
    exit(1);
}

open(MRNA,"<$ARGV[0]");          

$iden = <MRNA>;                  # Lectura de la primera linia del format FASTA ">XXXX".
@seql = <MRNA>;                  # Lectura de les seguents linies de la sequencia.
$mrna = "";                      # Variable que s'inicialitza amb la paraula buida, i a on hi posarem
                                 # tota la sequencia seguida.

# Per tal de posar la sequencia sencera en la variable $seq, concatenem els trossos de sequencia que 
# tenim a cada posicio del vector @seql.

$i = 0;
while ($i < scalar(@seql)){
    chomp($seql[$i]);
    $mrna = $mrna.$seql[$i];
    $i = $i + 1;
}

$mrna = uc($mrna);               # Transformacio de totes les bases de la sequencia a majúscules.

close(MRNA);                     # Es tanca el fitxer mRNA, un cop ja l'hem enregistrat a $mrna.



##### Passem la sequencia de mRNA a un vector base per base, i calculem la longitud d'aquest vector.

@mrna = split(//,$mrna);          
$n = scalar(@mrna);



############################################################################################
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
#VVV####################################################################################VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV#    C  O  S    D  E  L    P  R  O  G  R  A  M  A    P  R  I  N  C  I  P  A  L     #VVV#
#VVV#                                                                                  #VVV#
#VVV#									               #VVV#
#VVV####################################################################################VVV#
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#
############################################################################################



$inici = 0;                      ### Inici del patro a generar.
$llargada = 14;                  ### Llargada per defecte.
$contadordepatronsunics = 0;     ### Index de les posicions del vector @unic.

$x = 0;                          ### Inicialitzacio del comptador d'operacions a 0.
$r = "";

while ($inici <= $n - $llargada) {

    $patro = substr($mrna, $inici, $llargada);                ### Generacio de patrons

    ($r,$operacions) = correspondencia($mrna,$patro);

    if ($r == 1){                                             ### Crida a la funcio correspondencia
	$unic[$contadordepatronsunics] = $patro;              ### Patro trobat unic es guarda a @unic
	$contadordepatronsunics = $contadordepatronsunics + 1;
    }
    
    $x = $x + $operacions;

    $inici = $inici + 1;
}


$j = 0;
while ($j < scalar(@unic)) {
  print "patro unic: ", $unic[$j], "\n";
  $j = $j + 1;
}


print "el nombre d'operacions es $x\n";




#####################################################################################
#   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #
#00000000000000000000000000000000000000000000000000000000000000000000000000000000000#
#   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #  
#0000000#####################################################################0000000#
#   0   #						                    #   0   #
#0000000#						    		    #0000000#
#   0   #						                    #   0   #
#0000000#        F         U         N         C         I         O        #0000000#
#   0   #						                    #   0   #
#0000000#						                    #0000000#
#   0   #						                    #   0   #
#0000000#####################################################################0000000#
#   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #
#00000000000000000000000000000000000000000000000000000000000000000000000000000000000#
#   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #  
#####################################################################################



#########################################################################################################
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
#XX###################################################################################################XX#
#XX#			                        	                                             #XX#
#XX#########		                                                                     #########XX#
#XX#                                                                                                 #XX#
#XX#####		                                                                         #####XX#
#XX#					                                                             #XX#
#XX###              C  O  R  R  E  S  P  O  N  D  E  N  C  I  A      E  X  A  C  T  A              ###XX#
#XX#					                                                             #XX#
#XX####				                                                                 #####XX#
#XX#                                                                                                 #XX#
#XX#########			                                                             #########XX#
#XX#                                                                                                 #XX#
#XX###################################################################################################XX#
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
#########################################################################################################



# NOM: correspondencia
# PROPOSIT: Buscar per cada patro generat que se li passa com a segon parametre si es unic al mRNA, 
#           passat com a primer parametre.
# PARAMETRES: primer - mRNA a comprovar si el patro es unic o no.
#             segon  - patro generat que cal comprovar.
# RETORNA:o bé un 1 (cert) o 0 (fals) segons si el patro es unic o no al mrna.


sub correspondencia {

    my $mrna = $_[0];                    
    my $patro = $_[1];  

    my @mrna = split(//, $mrna);
    my $n = scalar(@mrna);

    my @patro = split(//,$patro);
    my $m = scalar(@patro);

    my $c = 0;
    my $s = 0;
    my $operacions = 0;
    
    while ($s <= $n - $m){

	$i = 0;
	$operacions = $operacions + 1;

	while ($i < $m && $mrna[$s+$i] eq $patro[$i]){
	    $i = $i + 1;
	    $operacions = $operacions + 1;
	    
	}
	if ($i == $m){
	    $c = $c + 1;
	}
	$s = $s + 1;
    }
    
    if ($c == 1){
	return (1,$operacions);
    }else{
	return (0,$operacions);
    }
}
