Todos los k-mers / n-gramos


21

Introducción

Hemos tenido histogramas y contando , pero no los hemos enumerado todos.

Cada año, Dyalog Ltd. celebra una competencia estudiantil. El desafío es escribir un buen código APL. Esta es una edición de independiente del sexto problema de este año.

Tengo permiso explícito para publicar este desafío aquí del autor original de la competencia. No dude en verificar siguiendo el enlace proporcionado y contactando al autor.

Problema

El término k-mer generalmente se refiere a todas las posibles subcadenas de longitud k que están contenidas en una cadena. En genómica computacional, los k-mers se refieren a todas las subsecuencias posibles (de longitud k ) de una lectura obtenida a través de la secuenciación de ADN. Escriba una función / programa que tome una cadena yk (la longitud de la subcadena) y devuelva / genere un vector de los k-mers de la cadena original.

Ejemplos

[4,"ATCGAAGGTCGT"]["ATCG","TCGA","CGAA","GAAG","AAGG","AGGT","GGTC","GTCG","TCGT"]

k > longitud de la cuerda? No devuelve nada / ningún resultado vacío:
[4,"AC"][]o ""o[""]


44
¿Importa el orden de salida? Cuando una subcadena ocurre varias veces, ¿debería repetirse en la salida?
Feersum

1
¿Puedo devolver una cadena de las subcadenas requeridas separadas por nuevas líneas en lugar de una matriz de cadenas, como esta ?
Leaky Nun

¿Podemos también ingresar y emitir la cadena como una matriz de caracteres (como en ['A', 'T', 'C', 'G']lugar de "ATCG"?
Adnan

¿Se permiten las respuestas Dyalog APL en este desafío PPCG (porque el desafío también está alojado por Dyalog)?
Kritixi Lithos

1
@feersum El orden es importante y las repeticiones deben repetirse. Esto es como una ventana deslizante.
Adám

Respuestas:


15

Gelatina , 1 byte

Jelly tiene un átomo diádico de un solo byte para esta misma operación

Pruébalo en línea! (el pie de página divide la lista resultante con nuevas líneas, para evitar que se imprima una representación borrosa).


1
De alguna manera, el OP debe haber sabido ...
Leaky Nun

1
@LeakyNun en realidad no lo hice.
Adám

8

Octava, 28 bytes

@(N,s)s((1:N)+(0:nnz(s)-N)')

Pruébalo en línea!

Para k> la longitud de la cadena funciona en Octave 4.2.1-windows pero en tio (Octave 4.0.3) no funciona.

Crea índices numéricos de elementos consecutivos e indexa la cadena por él.

s= "ATCGAAGGTCGT"
N = 4
idx = (1:N)+(0:nnz(s)-N)'
 =
    1    2    3    4
    2    3    4    5
    3    4    5    6
    4    5    6    7
    5    6    7    8
    6    7    8    9
    7    8    9   10
    8    9   10   11
    9   10   11   12

s(idx) =

ATCG
TCGA
CGAA
GAAG
AAGG
AGGT
GGTC
GTCG
TCGT



5

Brachylog , 3 bytes

s₎ᶠ

Pruébalo en línea!

Especificaciones:

  • Entrada: ["ATCGAAGGTCGT",4]
  • Argumento: Z
  • Salida: Z = ["ATCG","TCGA","CGAA","GAAG","AAGG","AGGT","GGTC","GTCG","TCGT"]

Cómo funciona

s₎ᶠ
s    Output is a substring of first element of input,
 ₎   with length specified by second element of input.
  ᶠ  Find all solutions.

5

Python 3 ,  47 45 42 bytes

-3 bytes gracias a los ovs (use el desempaquetado de Python 3 para reutilizar a[n-1:]en la cola).

f=lambda a,n:a[n-1:]and[a[:n],*f(a[1:],n)]

Una función recursiva que toma la cadena, ay la longitud de la porción n, y devuelve una lista de las rebanadas o una cadena vacía.

a[n-1:]toma una rebanada de la cadena actual de la n-1 ésimo (0 indexados) elemento hacia adelante a prueba si hay elementos suficientes restante (una cadena vacía es Falsey en Python) - esto es más corto que el equivalente len(a)>=n.

  • Si hay suficientes elementos, se construye una lista [...], con los primeros nelementos de la cadena,a[:n] y el resultado desempaquetado de llamada de la función, *f(...)con una versión quitado de la cola de la entrada actual (sin el primer elemento), a[1:].

  • Si no hay suficientes elementos, se alcanza la cola de la recursividad cuando a[n-1:] se devuelve (en este caso, una cadena vacía).

Pruébalo en línea!


45 para Python 2 o 3 con:

f=lambda a,n:a[n-1:]and[a[:n]]+f(a[1:],n)or[]

f=lambda a,n:a[n-1:]and[a[:n],*f(a[1:],n)]para 42 bytes (Python 3) TIO
ovs

@ovs, muy bien, he preguntado si esto es aceptable (ya que el resultado vacío es una cadena, mientras que el resultado no vacío es una lista).
Jonathan Allan

4

J , 2 bytes

,\

No es un programa completo, sino una función con un operador.

Llámalo como tal:

echo 4 ,\ 'ATCGAAGGTCGT'

Pruébalo en línea!

Cómo funciona

El operador (llamado "conjunción") \(llamado " infijo ") se usa como tal:

(x u\ y)aplica el verbo ua partes sucesivas de la lista y(llamadas infijos).

La función (llamada "verbo") uen este caso es la función ,que es una simple función " agregar ":

Crea una matriz que contiene los elementos de xseguido de los elementos de y.


3

Mathematica, 21 bytes

##~StringPartition~1&

Función anónima. Toma una cadena y un número (en ese orden) como entrada y devuelve una lista de cadenas como salida.


3

R, 65 61 bytes

-2 bytes gracias a MickyT

-2 bytes cambiando la indexación

devuelve una función anónima

function(s,n,x=nchar(s))`if`(n>x,'',substring(s,x:n-n+1,n:x))

substringrealiza un ciclo a través de los índices (a diferencia de los substrque no lo hacen), y si el índice inicial es menor que 1, su valor predeterminado es 1, por lo tanto, comprueba y devuelve la cadena vacía.

x:n-n+1es equivalente a 1:(x-n+1)ya que :tiene prioridad sobre sumas / diferencias

Pruébalo en línea!


puedes guardar un par de bytes con function(s,n,x=nchar(s))if(n>x,'',substring(s,1:(x-n+1),n:x))
MickyT

@MickyT, gracias! También noté que podía soltar algunos bytes cambiando el cálculo del índice
Giuseppe,


2

Medusa , 7 bytes

p
_I
\i

Pruébalo en línea!

Cómo funciona

En lineal:, p(\(I,i))donde pse imprime y \obtiene las subcadenas requeridas.

Ies la primera entrada sin procesar mientras que ies la segunda entrada evaluada.

En Jellyfish, cada función y operador obtiene dos argumentos, uno desde la derecha y otro desde la parte inferior. Aquí, la función pobtiene el argumento de la salida de _, que es necesaria si vamos a usar el operador \para obtener subcadenas.




2

Clojure, 19 bytes

Bueno, esto es útil:

#(partition % 1 %2)

Ejemplos:

(def f #(partition % 1 %2))
(println [(f 4 "ATCGAAGGTCGT")
          (f 4 "abc")])

[((A T C G) (T C G A) (C G A A) (G A A G) (A A G G) (A G G T) (G G T C) (G T C G) (T C G T))
 ()]

2

CJam , 4 bytes

{ew}

Bloque anónimo que espera los argumentos en la pila y deja el resultado en la pila después.

Pruébalo en línea!

ew es una función integrada que hace exactamente lo que se requiere.


55
Solo tengo una cosa que decir: ew
Adám

2

Retina , 41 38 bytes

.*$
$*
!&`(.)+(?=.*¶(?<-1>.)+(?(1)¶)$)

Pruébalo en línea!

Toma la cuerda y cuenta con líneas separadas. Las dos primeras líneas se utilizan para convertir el recuento de decimal a unario, por lo que si la entrada unaria es aceptable, el recuento de bytes se reducirá a 34 31. Editar: Guardado 3 bytes gracias a @FryAmTheEggman. O, si lo prefiere, una versión de 48 bytes que maneja nuevas líneas en la cadena, aunque eso produce resultados confusos:

.*$
$*
!&`(\S|\s)+(?=[\S\s]*¶(?<-1>.)+(?(1)$.)$)

@KritixiLithos No veo cómo su solución tiene en cuenta el recuento ...
Neil

Oh, lo siento, solo tuve un pedo cerebral> _ <
Kritixi Lithos

Esto no funciona necesariamente si la cadena puede contener una nueva línea, por lo que creo que puede cambiar (?!)a .
FryAmTheEggman

2

Octava con paquete de imágenes, 29 bytes

@(s,n)[im2col(+s, [1 n])' '']

Pruébalo en línea!

Explicación

La función im2col(m,b)toma una matriz m, extrae bloques de tamaño bde ella y los organiza como columnas. Por defecto, los bloques son deslizantes (en oposición a distintos). Aquí la matriz mes un vector de fila de los códigos ASCII de la cadena de entrada s(esto se hace como +s, que es más corto que el estándar double(s)), y el tamaño bes [1 n]para obtener bloques de nelementos deslizantes horizontalmente .

El resultado se transpone (usando la transposición de conjugado complejo ', que es más corta que la transposición .') para convertir las columnas en filas, y luego se convierte de nuevo en char ( [... '']que es más corto que el estándar char(...)).



1

Python 3 , 49 bytes

f=lambda a,n:[a[i:i+n]for i in range(len(a)-n+1)]

Pruébalo en línea!

Una solución no recursiva, aunque no más corta.

Compatible con Python 2.


Puede soltar f=, ahorrando dos bytes, porque no los usa en fningún otro lugar. Por defecto, las funciones que se declaran y no se pueden usar pueden dejarse sin nombre.
Sr. Xcoder

1

PHP, 75 bytes

Versión en línea

for([,$n,$s]=$argv;$i+$n-1<strlen($s);)$r[]=substr($s,$i++,$n);print_r($r);

80 bytes sin valores dobles

for([,$n,$s]=$argv;$i+$n-1<strlen($s);)$r[$p=substr($s,$i++,$n)]=$p;print_r($r);

1

Haskell, 39 bytes

n#s|length s<n=[]|1<2=take n s:n#tail s

Ejemplo de uso: 4 # "ABCDEF"-> ["ABCD","BCDE","CDEF"].Pruébalo en línea!

Una recursión simple que mantiene los primeros ncaracteres de la cadena de entrada y continúa con la cola de la cadena siempre que su longitud no sea menor que n.


1

Servidor SQL de Microsoft, 199 bytes

create function dbo.f(@s nvarchar(max),@ int)returns table as return
with v as(select 2 p,left(@s,@)g where len(@s)>=@ union all
select p+1,substring(@s,p,@)from v where len(@s)>p-2+@)select g from v

Revisalo.



1

Apilado , 7 bytes

infixes

Pruébalo en línea!

Bastante estándar Sin este incorporado, se convierte en 20 bytes:

{%x#'y-#+:>y#-#>x\#}

Cual es:

{%x#'y-#+:>y#-#>x\#}
{%                 }   dyad; first arg: x, second arg: y
  x#'                  length of x (the array)
     y-                minus y (the skew)
       #+              plus 1
         :>            range [x, y]
           y#-         y minus 1
              #>       range from [[x, y], [x, y] + y]
                x\#    get indices from x


1

C # 89 bytes

void a(string s,int n){for(int i=n;i<=s.Length;)Console.WriteLine(s.Substring(i++-n,n));}

Pruébalo en línea!

El mejor método que pude encontrar en C # es básicamente el mismo que Java


1

Ruby, 48 46 bytes

->(s,k){0.upto(s.size-k).map{|i|s[i..i+k-1]}}

No hay trucos particulares, solo un stabby-lambda que define una función que extrae la subcadena requerida de cada punto de partida válido.

Se guardaron dos bytes, ya que no parece ser necesario almacenar el lambda.


1

V , 16 bytes

òÀ|ly0Ïp
"_xòkVp

Me temo que no está muy bien golfizado, luchando con "eliminar la cadena si k> len (str)". La entrada está en el archivo, k es un argumento. Golf antes de la explicación

Pruébalo en línea!


¿Qué sucede si no intenta manejar el caso k> len (str)?
Adám

Dependiendo del método que use (en este caso en particular) simplemente deja la cadena como está
nmjcman101

1

ML estándar (mosml), 109 65 61 bytes

fun f(n,x)=if n>length(x)then[]else List.take(x,n)::f(n,tl x)

Toma un número y una lista de caracteres (una alternativa bastante común a las cadenas en el mundo SML). (Realmente funciona en todas las listas, por supuesto).

Uso:

- f(3,explode("ABCDEFGH"));
> val it =
    [[#"A", #"B", #"C"], [#"B", #"C", #"D"], [#"C", #"D", #"E"],
     [#"D", #"E", #"F"], [#"E", #"F", #"G"], [#"F", #"G", #"H"]] :
  char list list
- f(7, explode("ABCD"));
> val it = [] : char list list

Registro de cambios:

  • Correcto, hay una biblioteca estándar ... (-44 bytes)
  • Cambie la comparación y nula a [] como se sugiere (-4 bytes)

1
Puede guardar un byte cambiando if length(x)<n thena if n>length(x)then. Sin embargo, como es perfectamente posible que SML maneje cadenas, no estoy seguro de que se requiera explodeque ya se aplique a la cadena de entrada.
Laikoni

También then nil elsese puede acortar a then[]else.
Laikoni

@Laikoni tampoco está seguro, pero ¯ \ _ (ツ) _ / ¯
L3viathan

Usando algunas otras funciones de la biblioteca, obtuve una versión de 68 bytes que trata con cadenas en lugar de listas de caracteres. También su enfoque puede ser acortado a 54 bytes: fun f$n=if n>length$then[]else List.take($,n)::f(tl$)n.
Laikoni

1

JavaScript (Firefox 30-57), 51 bytes

(s,n,t='')=>[for(c of s)if((t+=c)[n-1])t.slice(-n)]

64 bytes en ES6:

(s,n,t=s.slice(0,--n))=>[...s.slice(n)].map(c=>(t+=c).slice(~n))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.