<div dir="ltr"><div>Hola,<br><br>he leído el correo tarde (hace dos días). Así que, no sé sí llego tarde con mis soluciones.<br><br>Pero me ha gustado mucho el problema, le he dado un par de vueltas y por sí aún sirve de algo, ahí van.<br><br></div><div>Antes, pero, me gustaría saber si la operación que describe el problema tiene algún nombre en bioinformática o biología? Simple curiosidad. Gracias!<br></div><div><br>En las dos soluciones propuestas, asumo que la longitud de cada cadena de entrada es la misma.<br>He probado cada solución con cuatro entradas diferentes.<br>  <br>1.
 Mi primera idea consiste en descomponer las cadenas en arrays, formando
 un array de arrays (matriz). Traspongo la matriz resultante y elimino 
de esta todas las filas que contienen 'N'. El resultado, lo vuelvo a 
trasponer y de cada fila formo una nueva cadena (join de cada elemento 
de la fila). Estas nuevas cadenas forman el resultado final.<br><br>#!/usr/bin/env perl<br><br>use strict;<br>use warnings;<br>use Data::Dumper;<br><br>#my @in = qw( ABCDN ANHYI ABCDE );<br><br>#my @in = qw( ABCDN AHYNI ABCDE ABNCD AHNYI EDCBA ANBCD NAHYI CDEBA );<br><br>#my @in = qw( ABCDEF GHIJKL MOPQRS );<br><br>my @in = qw( CAGGCDGGNACACDACGAG AGCGCDGGNACACDNCGAG ACGGCDGGCACACDACAGG GACGCDGGADCACDACGGA );<br><br>#decompose strings<br>my @list1;<br>push @list1, map [ split // ], @in;<br><br>print Dumper(\@list1);<br><br>#transpose and sieve out<br>my @list2;<br>foreach my $j (0 .. $#{$list1[0]}) {<br>  my $t = [ map $_->[$j], @list1 ];<br>  next if grep $_ eq 'N', @$t;<br>  push @list2, $t;<br>}<br><br>print Dumper(\@list2);<br><br>#transpose and compose strings<br>my @list3;<br>foreach my $j (0 .. $#{$list2[0]}) {<br>  push @list3, join '', map $_->[$j], @list2;<br>}<br><br>print Dumper(\@list3);<br><br>#print result<br>print "$_\n" foreach @list3;<br><br><br>2.
 Como segunda solución, mediante un hash acumulo todos los indices en 
los que se encuentra una 'N'. Una vez que tengo todos los indices, 
descompongo en un array cada cadena (splice) y extraigo con slice todos 
aquellos elementos cuyo indice NO se encuentra en el conjunto de indices
 calculados anteriormente. Finalmente, vuelvo a construir nuevas cadenas
 con join a partir de la descomposición de cada una de ellas.<br><br>#!/usr/bin/env perl<br><br>use strict;<br>use warnings;<br><br>my @in = qw( ABCDN ANHYI ABCDE );<br><br>#my @in = qw( ABCDN AHYNI ABCDE ABNCD AHNYI EDCBA ANBCD NAHYI CDEBA );<br><br>#my @in = qw( ABCDEF GHIJKL MOPQRS );<br><br>#my @in = qw( CAGGCDGGNACACDACGAG AGCGCDGGNACACDNCGAG ACGGCDGGCACACDACAGG GACGCDGGADCACDACGGA );<br><br>my %m;<br>foreach ( @in ) {<br>  $m{ $-[0] }++ while $_ =~ /N/g<br>};<br><br>foreach ( @in ) {<br>  print join '', (split //)[ grep { not exists $m{$_} } 0 .. length($in[0])-1 ], "\n";<br>}<br><br><br></div>Have fun!<br><br><br>El 3 de febrero de 2015, 11:47, Verónica Olmos González <span dir="ltr"><<a href="mailto:volmosg.bt@gmail.com" target="_blank">volmosg.bt@gmail.com</a>></span> escribió:<br></div><div class="gmail_extra"><br><div class="gmail_quote">El 3 de febrero de 2015, 11:47, Verónica Olmos González <span dir="ltr"><<a href="mailto:volmosg.bt@gmail.com" target="_blank">volmosg.bt@gmail.com</a>></span> escribió:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>Muchísimas gracias por las respuestas.<br><br></div>De momento, he probado lo de la máscara que me ha sugerido Salvador (no tenía ni idea de que se podía hacer eso) y, salvo porque los elementos del array no recuperan so longitud original después de la eliminación (no sé si esto es la consecuencia lógica esperable; pero seguiré echándole un ojo), me soluciona bastante bien el problema que tenía :)<br><br></div>Lo dicho, muchas gracias, y seguiré investigando con las cosillas que me habéis ido diciendo!<br></div><div class="gmail_extra"><br><div class="gmail_quote">El 3 de febrero de 2015, 8:17, H. Daniel Cesario <span dir="ltr"><<a href="mailto:maneta@gmail.com" target="_blank">maneta@gmail.com</a>></span> escribió:<div><div class="h5"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>Igual podrías mirar la funcion grep de perl:http://<a href="http://perlmaven.com/filtering-values-with-perl-grep" target="_blank">perlmaven.com/filtering-values-with-perl-grep</a></div><div>Y filtrar la array de entrada quitando los elementos que no te interesan. Ej:</div><div><span style="background-color:rgba(255,255,255,0)">my @arr2 = grep </span><span style="background-color:rgba(255,255,255,0)">{</span><span style="background-color:rgba(255,255,255,0)"> $_ </span><span style="background-color:rgba(255,255,255,0)">=~</span><span style="background-color:rgba(255,255,255,0)"> </span><span style="background-color:rgba(255,255,255,0)">/(?!N)</span><span style="background-color:rgba(255,255,255,0)">/</span><span style="background-color:rgba(255,255,255,0)"> </span><span style="background-color:rgba(255,255,255,0)">}</span><span style="background-color:rgba(255,255,255,0)"> @arr1</span><span style="background-color:rgba(255,255,255,0)">;</span></div><div><br></div><div>No estoy seguro de la regex(dont shoot the messenger)</div><div><br></div><div>Pero el grep igual te ayuda!</div><div><br></div><div>Salut y Perl</div><div><br>Sent from my iPhone</div><div><div><div><br>On 3/2/2015, at 8:00, JJ Merelo <<a href="mailto:jjmerelo@gmail.com" target="_blank">jjmerelo@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">Madre mía, qué hack. Aplausos. <br></div><div class="gmail_extra"><br><div class="gmail_quote">El 2 de febrero de 2015, 22:42, Salvador Fandiño <span dir="ltr"><<a href="mailto:sfandino@gmail.com" target="_blank">sfandino@gmail.com</a>></span> escribió:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000"><div><div>
    <div>On 02/02/2015 08:58 PM, Verónica Olmos
      González wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">
        <div>
          <div>
            <div>
              <div>¡Hola a todos!<br>
                <br>
                Bueno, ante todo, como decía en mi presentación, soy
                bastante (muy) novata en Perl, así que es bastante
                probable que la esté liando con algo muy básico... pero
                me gustaría compartir mi problema con vosotros, por si
                alguno supiera darme alguna orientación (aunque sea
                simplemente remitirme a alguna página concreta de
                documentación).<br>
                <br>
              </div>
              El contexto de mi problema es el siguiente: parto de un
              array que contiene secuencias de nucleótidos (o sea,
              strings que deben estar formados por "A", "C", "G" o "T").
              La cosa es que estos strings pueden contener, cualquiera
              de ellos, en determinada posición, el carácter "N", que no
              es "válido". Lo que hace el resto de mi programa es hacer
              comparaciones dos a dos entre cada elemento del array. Lo
              que quiero hacer, y el quid de mi duda: si en "x" posición
              de cualquier elemento encuentro una "N", debo borrar esa
              "x-ésima" posición en TODOS los elementos del array. Un
              ejemplo: si tengo @arr = ("AATN", "AATG", "TATG") debo
              quedarme con @arr2 = ("AAT", "AAT", "TAT").<br>
              <br>
            </div>
            Sin enrollarme con más explicaciones, os enseño el código
            con mi planteamiento:<br>
            <br>
          </div>
          <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><font><span style="font-family:monospace,monospace">@sequences =
                ("AATGTCAACGAN", "AATGTCAACGNA", "ATTGTCAACGTN",
                "ATTGTGATCGTT");</span></font><br>
            <font><span style="font-family:monospace,monospace">for ($i
                = 0; $i <= scalar(@sequences); $i++) {</span></font><br>
            <font><span style="font-family:monospace,monospace">    if
                ($sequences[$i] =~ "N") {</span></font><br>
            <font><span style="font-family:monospace,monospace"></span></font></blockquote>
        </div>
        <blockquote><font><span style="font-family:monospace,monospace">     
              # Localizo las "N" y guardo su posición en un array</span></font><br>
          <font><span style="font-family:monospace,monospace"></span></font></blockquote>
        <div>
          <blockquote>
            <div><font><span style="font-family:monospace,monospace">   
                      push(@pos,index($sequences[$i], "N"));<br>
                      }<br>
                  }<br>
                  <br>
                </span></font></div>
            <div><font><span style="font-family:monospace,monospace">#
                  Elimino posiciones repetidas y ordeno los valores<br>
                </span></font></div>
            <div><font><span style="font-family:monospace,monospace">my
                  @pos = do { my %seen; grep { !$seen{$_}++ } @pos };<br>
                  @pos = sort @pos;<br>
                  <br>
                </span></font></div>
            <div><font><span style="font-family:monospace,monospace">#
                  Mi idea era, mediante expresiones regulares, poner "N"
                  en todos los elementos de los arrays, en las
                  posiciones guardadas, para luego eliminarlo todo
                  evitando "corrimientos" en las posiciones<br>
                </span></font></div>
          </blockquote>
          <div>
            <blockquote><font><span style="font-family:monospace,monospace">for ($i = 0;
                  $i <= scalar(@sequences); $i++) {</span></font><br>
              <font><span style="font-family:monospace,monospace">   
                  for ($j = 0; $j <= scalar(@pos); $j++) {</span></font><br>
              <font><span style="font-family:monospace,monospace">   
                      substr($sequences[$i],$pos[$j],1) =~ s/\D/N/;</span></font><br>
              <font><span style="font-family:monospace,monospace">    }</span></font><br>
              <font><span style="font-family:monospace,monospace">}</span></font><br>
              <br>
            </blockquote>
            Ahora bien, en el último bucle se me va todo de madre,
            permanece iterando continuamente.<br>
            <br>
          </div>
          <div>La verdad es que seguro que estoy haciendo fatal algo
            tontísimo, pero no soy capaz de ver el origen del error, por
            lo que agradecería enormemente cualquier tipo de
            orientación.<br>
            <br>
            <br>
          </div>
          <div>Un saludo,<br>
          </div>
          <div>Verónica<br>
          </div>
          <div>
            <div>
              <div>
                <div>
                  <div><br>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br></div></div>
    Para esto de la N hay un truco.<br>
    <br>
    Si te fijas, de todos los caracteres AGCTN solo la N tiene un 1 en
    el bit 3 (0x08) asi que puedes detectar donde hay Ns haciendo un OR
    de todas las sequencias y luego buscando los caracteres que tienen
    ese bit a uno en el resultado.<br>
    <br>
    A partir de ahi es fácil generar una mascara que al hacer AND con
    las secuencias originales ponga a cero las posiciones con N, y luego
    solo hay que borrar los ceros:<span><br>
    <br>
      @sequences = ("AATGTCAACGAN",<br>
                    "AATGTCAACGNA",<br>
                    "ATTGTCAACGTN",<br>
                    "ATTGTGATCGTT");<br>
    <br></span>
      my $mask = '';<br>
      $mask |= $_ for @sequences;<br>
      $mask =~ s/(.)/(ord($1) & 8) ? "\0" : "\xFF"/ge;<br>
    <br>
      for (@sequences) {<br>
          $_ &= $mask;<br>
          tr/\0//;<br>
      }<br>
    <br>
      use Data::Dumper;<br>
      print Dumper \@sequences;<br>
    <br>
    <br>
  </div>

<br>_______________________________________________<br>
llista dels Barcelona-pm<br>
<a href="mailto:Barcelona-pm@pm.org" target="_blank">Barcelona-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/barcelona-pm" target="_blank">http://mail.pm.org/mailman/listinfo/barcelona-pm</a><br>
BCN Perl Mongers: <a href="http://barcelona.pm.org" target="_blank">http://barcelona.pm.org</a><br></blockquote></div><br><br clear="all"><br>-- <br><div>JJ</div>
</div>
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>llista dels Barcelona-pm</span><br><span><a href="mailto:Barcelona-pm@pm.org" target="_blank">Barcelona-pm@pm.org</a></span><br><span><a href="http://mail.pm.org/mailman/listinfo/barcelona-pm" target="_blank">http://mail.pm.org/mailman/listinfo/barcelona-pm</a></span><br><span>BCN Perl Mongers: <a href="http://barcelona.pm.org" target="_blank">http://barcelona.pm.org</a></span></div></blockquote></div></div></div><br>_______________________________________________<br>
llista dels Barcelona-pm<br>
<a href="mailto:Barcelona-pm@pm.org" target="_blank">Barcelona-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/barcelona-pm" target="_blank">http://mail.pm.org/mailman/listinfo/barcelona-pm</a><br>
BCN Perl Mongers: <a href="http://barcelona.pm.org" target="_blank">http://barcelona.pm.org</a><br></blockquote></div></div></div><br><br clear="all"><br>-- <br><span class=""><div><div dir="ltr">Verónica Olmos González<br>Skype: v.olmosg<br>Teléfono/Phone: <a href="tel:%2B34%20666%2068%2016%2001" value="+34666681601" target="_blank">+34 666 68 16 01</a><br></div></div>
</span></div>
<br>_______________________________________________<br>
llista dels Barcelona-pm<br>
<a href="mailto:Barcelona-pm@pm.org">Barcelona-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/barcelona-pm" target="_blank">http://mail.pm.org/mailman/listinfo/barcelona-pm</a><br>
BCN Perl Mongers: <a href="http://barcelona.pm.org" target="_blank">http://barcelona.pm.org</a><br></blockquote></div><br></div>