Tutti i k-mers / n-grammi


21

Intro

Abbiamo avuto istogrammi e conteggi , ma non li abbiamo elencati tutti.

Ogni anno, Dyalog Ltd. organizza una competizione studentesca. La sfida è scrivere un buon codice APL. Questa è un'edizione linguistica indipendente dal del sesto problema di quest'anno.

Ho il permesso esplicito di pubblicare questa sfida qui dall'autore originale del concorso. Sentiti libero di verificare seguendo il link fornito e contattando l'autore.

Problema

Il termine k-mer si riferisce in genere a tutte le possibili sottostringhe di lunghezza k contenute in una stringa. Nella genomica computazionale, i k-mer si riferiscono a tutte le possibili sottosequenze (di lunghezza k ) da una lettura ottenuta attraverso il DNA Sequencing. Scrivi una funzione / programma che accetta una stringa e k (la lunghezza della sottostringa) e restituisce / genera un vettore dei k-metri della stringa originale.

Esempi

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

k > lunghezza della stringa? Restituisce nulla / nessun risultato vuoto:
[4,"AC"][]o ""o[""]


4
L'ordine dell'output è importante? Quando una sottostringa si verifica più volte, dovrebbe essere ripetuta nell'output?
feersum

1
Posso restituire una stringa delle sottostringhe richieste separate da newline invece di una matrice di stringhe, come questa ?
Perdente suora

Possiamo anche inserire e generare la stringa come una matrice di caratteri (come ['A', 'T', 'C', 'G']invece di "ATCG"?
Adnan,

Le risposte APL di Dyalog sono consentite in questa sfida PPCG (perché la sfida è ospitata anche da Dyalog)?
Kritixi Lithos

1
@feersum L'ordine è importante e le ripetizioni devono essere ripetute. Questo è proprio come una finestra scorrevole.
Adám,

Risposte:


15

Gelatina , 1 byte

Jelly ha un atomo diadico a byte singolo proprio per questa operazione

Provalo online! (il piè di pagina divide l'elenco risultante con nuove righe, per evitare la stampa di una rappresentazione confusa).


1
In qualche modo l'OP deve aver saputo ...
Leaky Nun

1
@LeakyNun In realtà non l'ho fatto.
Adám,

8

Ottava, 28 byte

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

Provalo online!

Per k> la lunghezza della stringa funziona in Octave 4.2.1-windows ma in tio (Octave 4.0.3) non funziona.

Crea indici numerici di elementi consecutivi e indicizza la stringa da esso.

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 byte

s₎ᶠ

Provalo online!

Specifiche:

  • Ingresso: ["ATCGAAGGTCGT",4]
  • Discussione: Z
  • Produzione: Z = ["ATCG","TCGA","CGAA","GAAG","AAGG","AGGT","GGTC","GTCG","TCGT"]

Come funziona

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 byte

-3 byte grazie agli ovs (usa il disimballaggio di Python 3 per riutilizzarlo a[n-1:]alla coda).

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

Una funzione ricorsiva che prende la stringa ae la lunghezza della sezione ne restituisce un elenco delle sezioni o una stringa vuota.

a[n-1:]prende una fetta della stringa corrente dall'elemento n-1 ° (0-indicizzato) in poi per verificare se ci sono abbastanza elementi rimanenti (una stringa vuota è falsa in Python) - questo è più corto dell'equivalente len(a)>=n.

  • Se ci sono elementi sufficienti, viene creato un elenco [...], con i primi nelementi della stringa, a[:n]e il risultato decompresso di richiamare nuovamente la funzione *f(...), con una versione dequeued dell'input corrente (senza il primo elemento),a[1:] .

  • Se non ci sono abbastanza elementi, la coda della ricorsione viene raggiunta quando a[n-1:]viene restituita (in questo caso una stringa vuota).

Provalo online!


45 per 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)]per 42 byte (Python 3) TIO
ovs

@ovs, molto bello, ho chiesto se questo è accettabile (dal momento che il risultato vuoto è una stringa, mentre il risultato non vuoto è un elenco).
Jonathan Allan,

4

J , 2 byte

,\

Non è un programma completo, ma una funzione con un operatore.

Chiamalo come tale:

echo 4 ,\ 'ATCGAAGGTCGT'

Provalo online!

Come funziona

L'operatore (chiamato "congiunzione") \(chiamato " infisso ") viene utilizzato come tale:

(x u\ y)applica il verbo ualle parti successive dell'elenco y(chiamate infissi).

La funzione (chiamata "verbo") uin questo caso è la funzione ,che è una semplice " append " ":

Crea una matrice contenente gli elementi di xseguiti dagli elementi di y.


3

Mathematica, 21 byte

##~StringPartition~1&

Funzione anonima. Accetta una stringa e un numero (in quell'ordine) come input e restituisce un elenco di stringhe come output.


3

R, 65 61 byte

-2 byte grazie a MickyT

-2 byte modificando l'indicizzazione

restituisce una funzione anonima.

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

substringscorre ciclicamente gli indici (al contrario di quelli substrche non lo fanno) e se l'indice iniziale è inferiore a 1, viene impostato 1invece su default , quindi controlla e restituisce la stringa vuota.

x:n-n+1è equivalente a 1:(x-n+1)poiché :ha la precedenza su somme / differenze

Provalo online!


puoi salvare un paio di byte con function(s,n,x=nchar(s))if(n>x,'',substring(s,1:(x-n+1),n:x))
MickyT

@MickyT, grazie! Ho anche notato che potevo eliminare alcuni byte modificando il calcolo dell'indice
Giuseppe,


2

Medusa , 7 byte

p
_I
\i

Provalo online!

Come funziona

In lineare: p(\(I,i))dove si ptrova la stampa e \ottiene le sottostringhe richieste.

Iè il primo input non elaborato mentre iè il secondo input valutato.

In Jellyfish, ogni funzione e operatore ottiene due argomenti, uno da destra e uno da fondo. Qui, la funzione pottiene l'argomento dall'output di _, che è necessario se vogliamo usare l'operatore \per ottenere sottostringhe.




2

Clojure, 19 byte

Bene, questo è utile:

#(partition % 1 %2)

Esempi:

(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 byte

{ew}

Blocco anonimo che prevede gli argomenti nello stack e lascia il risultato nello stack dopo.

Provalo online!

ew è un built-in che fa esattamente ciò che è richiesto.


5
Ho solo una cosa da dire: ew
Adám,

2

Retina , 41 38 byte

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

Provalo online!

Prende la stringa e conta su righe separate. Le prime due righe vengono utilizzate per convertire il conteggio da decimale a unario, quindi se l'input unario è accettabile, il conteggio dei byte verrebbe ridotto a 34 31. Modifica: 3 byte salvati grazie a @FryAmTheEggman. Oppure, se preferisci, una versione a 48 byte che gestisce le nuove righe nella stringa, sebbene ciò produca un output confuso:

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

@KritixiLithos Non vedo come la tua soluzione tenga conto del conteggio ...
Neil,

Oh, scusa se ho appena avuto una scoreggia cerebrale> _ <
Kritixi Lithos

Questo non funziona necessariamente se la stringa può contenere una nuova riga, quindi penso che tu possa cambiare (?!)in .
FryAmTheEggman,

2

Ottava con pacchetto immagine, 29 byte

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

Provalo online!

Spiegazione

La funzione im2col(m,b)prende una matrice m, ne estrae blocchi di dimensioni be li dispone come colonne. Di default i blocchi sono scorrevoli (al contrario di distinti). Qui la matrice mè un vettore di riga dei codici ASCII della stringa di input s(questo viene fatto come +s, che è più corto dello standard double(s)), e la dimensione bè quella [1 n]di ottenere blocchi di nelementi scorrevoli orizzontalmente .

Il risultato viene trasposto (usando la trasposizione coniugata complessa ', che è più corta della trasposizione .') per trasformare le colonne in righe, quindi viene riconvertito in carattere ( [... '']che è più corto dello standard char(...)).



1

Python 3 , 49 byte

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

Provalo online!

Una soluzione non ricorsiva, sebbene non più breve.

Compatibile con Python 2.


È possibile eliminare f=, salvando due byte, perché non si utilizza faltrove. Per impostazione predefinita, le funzioni appena dichiarate e non utilizzate possono essere lasciate senza nome.
Mr. Xcoder,

1

PHP, 75 byte

Versione online

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

80 byte senza doppi valori

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

1

Haskell, 39 byte

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

Esempio di utilizzo: 4 # "ABCDEF"-> ["ABCD","BCDE","CDEF"]. Provalo online!

Una semplice ricorsione che mantiene i primi ncaratteri della stringa di input e continua con la coda della stringa purché la sua lunghezza non sia inferiore n.


1

Microsoft SQL Server, 199 byte

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

Controllalo.



1

Impilato , 7 byte

infixes

Provalo online!

Piuttosto standard. Senza questo built-in, diventa 20 byte:

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

Che è:

{%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 byte

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

Provalo online!

Il metodo migliore che ho trovato in C # è sostanzialmente lo stesso di Java


1

Rubino, 48 46 byte

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

Nessun trucco particolare, solo un stabby-lambda che definisce una funzione che tira la sottostringa richiesta da ciascun punto di partenza valido.

Due byte salvati, poiché non sembra essere necessario memorizzare la lambda.


1

V , 16 byte

òÀ|ly0Ïp
"_xòkVp

Temo non molto bene il golf, lottando con "cancella la stringa se k> len (str)". L'input è nel file, k è un argomento. Giocare a golf prima della spiegazione

Provalo online!


Cosa succede se non provi a gestire il caso k> len (str)?
Adám,

A seconda del metodo che uso (in questo in particolare) lascia la stringa così com'è
nmjcman101

1

ML standard (mosml), 109 65 61 byte

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

Prende un numero e un elenco di caratteri (un'alternativa abbastanza comune alle stringhe nel mondo SML). (Funziona davvero su tutti gli elenchi ovviamente.)

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

changelog:

  • Esatto, c'è una libreria standard .. (-44 byte)
  • Cambia confronto e zero in [] come suggerito (-4 byte)

1
È possibile salvare un byte cambiando if length(x)<n thenin if n>length(x)then. Tuttavia, poiché SML è perfettamente in grado di gestire le stringhe, non sono sicuro che sia necessario richiedere che explodesia già applicato alla stringa di input.
Laikoni,

Inoltre then nil elsepuò essere abbreviato in then[]else.
Laikoni,

@Laikoni non è neanche sicuro, ma ¯ \ _ (ツ) _ / ¯
L3viathan

Usando alcune altre funzioni di libreria ho ottenuto una versione da 68 byte che si occupa di stringhe invece di liste di caratteri. Anche il tuo approccio può essere ridotto a 54 byte: fun f$n=if n>length$then[]else List.take($,n)::f(tl$)n.
Laikoni,

1

JavaScript (Firefox 30-57), 51 byte

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

64 byte in ES6:

(s,n,t=s.slice(0,--n))=>[...s.slice(n)].map(c=>(t+=c).slice(~n))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.