Tüm k-mer / n gram


21

giriş

Histogramlarımız ve saymamız vardı ama hepsini listelemiyoruz.

Dyalog Ltd. her yıl bir öğrenci yarışması düzenliyor. Buradaki zorluk , iyi bir APL kodu yazmaktır . Bu, bu yılın altıncı sorunun bir dil agnostik sürümüdür.

Bu zorluğu yarışmanın asıl yazarından buraya göndermek için açıkça iznim var. Verilen bağlantıyı takip ederek ve yazarla iletişim kurarak doğrulamaktan çekinmeyin .

Sorun

K-mer terimi, tipik olarak , bir dizgede bulunan ve k uzunluğundaki tüm olası alt dizileri belirtir. Hesaplamalı genomikte, k-merciler , DNA Sekanslama ile elde edilen bir okumadan mümkün olan tüm alt dizilere ( k uzunluğu ) atıfta bulunur . Bir dizgeyi ve k'yi (alt dize uzunluğu) alan ve orijinal dizgenin k-mercilerinin bir vektörünü döndüren / veren bir işlev / program yazın .

Örnekler

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

k > string uzunluğu? Hiçbir şey / boş sonuç vermeyin:
[4,"AC"][]veya ""veya[""]


4
Çıktının sırası önemli mi? Bir alt halka birden çok kez meydana geldiğinde, çıktıda tekrarlanmalı mı?
feersum

1
Ben gibi yerine dizelerden oluşan bir dizinin satırbaşıyla ayrılmış gerekli alt dizeleri, bir dizi iade edebilir bu ?
Sızdıran Rahibe

Dizgiyi bir karakter dizisi olarak da girip çıkartabilir miyiz ( ['A', 'T', 'C', 'G']bunun yerine "ATCG"?
Adnan

Dyalog APL cevaplarına bu PPCG mücadelesinde izin veriliyor mu (çünkü bu zorluk Dyalog tarafından da barındırılıyor)?
Kritixi Lithos

1
@ feersum Sipariş önemlidir ve tekrarlamalar tekrarlanmalıdır. Bu sadece kayan bir pencere gibidir.
Adám

Yanıtlar:



8

Octave, 28 bayt

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

Çevrimiçi deneyin!

K> için dize uzunluğu Octave 4.2.1 pencerelerinde çalışır, ancak tioda (Octave 4.0.3) çalışmaz.

Ardışık öğelerin sayısal dizinlerini oluşturur ve dizeyi onun tarafından dizine alır.

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 bayt

s₎ᶠ

Çevrimiçi deneyin!

Özellikleri:

  • Giriş: ["ATCGAAGGTCGT",4]
  • Bağımsız değişken: Z
  • Çıktı: Z = ["ATCG","TCGA","CGAA","GAAG","AAGG","AGGT","GGTC","GTCG","TCGT"]

Nasıl çalışır

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 bayt

Ovs sayesinde -3 bayt ( a[n-1:]kuyrukta tekrar kullanmak için Python 3'ün ambalajını kullanın .)

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

Dizeyi ave dilim uzunluğunu nalan ve dilimler listesini veya boş bir dize döndüren özyinelemeli bir işlev .

a[n-1:]Kalan yeterli dize olup olmadığını test etmek için n- 1'inci (0-indeksli) elemandan mevcut dizginin bir dilimini alır (boş bir dize Python'da falseydir) - bu eşdeğerden daha kısadır len(a)>=n.

  • Yeterli eleman varsa , dizinin [...]ilk nelemanları ile bir liste oluşturulur ve dizilimin a[:n]açılmamış sonucu *f(...), mevcut girişin boşaltılmış bir versiyonuyla (ilk eleman olmadan) tekrar çağırılır a[1:].

  • Yeterli eleman yoksa, özyinelemenin kuyruğuna a[n-1:]geri dönüldüğünde ulaşılır (bu durumda boş bir ip).

Çevrimiçi deneyin!


45 Python 2 ya da 3:

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)]42 bayt (Python 3) için TIO
ovs

@ovs, çok hoş, bunun kabul edilebilir olup olmadığını sordum (boş sonuç bir dize iken boş sonuç, bir liste iken).
Jonathan Allan

4

J , 2 bayt

,\

Bu tam bir program değil, operatörlü bir fonksiyondur.

Buna şöyle diyoruz:

echo 4 ,\ 'ATCGAAGGTCGT'

Çevrimiçi deneyin!

Nasıl çalışır

İşleç ("bağlantı" olarak \adlandırılır ) (" infix " olarak adlandırılır ) aşağıdaki gibi kullanılır:

(x u\ y)fiili ulistenin ardışık kısımlarına uygular y(ekler olarak adlandırılır).

( "Fiil" olarak adlandırılır) fonksiyonu ubu durumda fonksiyonudur ,bir basit " ekleme " fonksiyonu:

Öğelerini ve xardından öğelerini içeren bir dizi oluşturur y.


3

Mathematica, 21 bayt

##~StringPartition~1&

Anonim işlev Girdi olarak bir dize ve sayı alır (bu sırada) ve çıktı olarak dizelerin bir listesini döndürür.


3

R, 65 61 bayt

MickyT sayesinde -2 bayt

İndekslemeyi değiştirerek -2 bayt

isimsiz bir işlev döndürür.

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

substringendeksler arasında geçiş yapar ( substrhangisinin aksine ) ve başlangıç ​​endeksi 1'den küçükse, bunun 1yerine varsayılan değerdir, bu yüzden boş dizeyi kontrol eder ve döndürür.

x:n-n+1toplamlara / farklılıklara göre öncelikli 1:(x-n+1)olduğundan , buna eşittir:

Çevrimiçi deneyin!


function(s,n,x=nchar(s))if ile birkaç byte tasarruf edebilirsiniz(n>x,'',substring(s,1:(x-n+1),n:x))
MickyT

@MickyT, teşekkürler! Ayrıca endeks hesaplamasını değiştirerek bazı baytları bırakabileceğimi de farkettim
Giuseppe


2

Denizanası , 7 bayt

p
_I
\i

Çevrimiçi deneyin!

Nasıl çalışır

Doğrusal olarak:, p(\(I,i))nerede pbasılır ve \istenen alt dizeleri alır.

IHam birinci girdi iken ideğerlendirilen ikinci girdidir.

Denizanası'nda her işlev ve operatör, biri sağdan diğeri diğeri olmak üzere iki argüman alır. Burada, işlev p, alt dizgileri almak _için işleci kullanmamız gerekirse gerekli olan çıktının argümanını alır \.




2

Clojure, 19 bayt

Peki bu kullanışlı:

#(partition % 1 %2)

Örnekler:

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

{ew}

Yığındaki argümanları bekleyen ve sonucu yığında bırakan adsız blok.

Çevrimiçi deneyin!

ew tam olarak ne gerekiyorsa onu yapan bir yerleşiktir.


5
Söyleyecek tek bir şeyim var: ew
Adám

2

Retina , 41 38 bayt

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

Çevrimiçi deneyin!

Dizeyi alır ve ayrı satırlarda sayma. İlk iki satır sayımı ondalık sayıdan birime dönüştürmek için kullanılır, bu nedenle unary girişi kabul edilebilirse bayt sayısı 34 31'e düşürülür . Düzenleme: @FryAmTheEggman sayesinde 3 bayt kaydedildi. Veya tercih ederseniz, dizede yeni satırları işleyen, ancak kafa karıştırıcı çıktılar veren 48 baytlık bir sürüm:

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

@KritixiLithos Çözümünüzü nasıl hesaba katacağını anlamıyorum ...
Neil

Oh, üzgünüm sadece bir beyin osuruğu vardı> _ <
Kritixi Lithos

Dize Yeni satır içerebilir eğer değiştirebileceğiniz düşünüyorum böylece bu mutlaka çalışmıyor (?!)için .
FryAmTheEggman

2

Görüntü Paketi ile birlikte Octave , 29 byte

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

Çevrimiçi deneyin!

açıklama

İşlev im2col(m,b)bir matris alır m, boyut bloklarını bondan ayıklar ve bunları sütun olarak düzenler. Varsayılan olarak, bloklar kaymaktadır (farklı olarak). Burada matris m, giriş dizesinin ASCII kodlarının bir sıra vektörüdür s(bu, +sstandarttan daha kısa olarak yapılır double(s)) ve boyut b, [1 n]yatay olarak kayan neleman blokları elde etmektir .

Sonuç, kolonları sıralara çevirmek için transpoze edilir (transpozitten 'daha kısa olan karmaşık konjuge transpozit kullanılarak .') ve daha sonra tekrar char'a ( [... '']standarttan daha kısa olan char(...)) dönüştürülür.



1

Python 3 , 49 bayt

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

Çevrimiçi deneyin!

Kısa olmamakla birlikte özyinelemeli olmayan bir çözüm.

Python 2 ile uyumludur.


f=İki bayt kaydederek bırakabilirsiniz , çünkü fbaşka hiçbir yerde kullanmazsınız . Varsayılan olarak, yalnızca bildirilen ve kullanılmayan işlevler adsız bırakılabilir.
Bay Xcoder

1

PHP, 75 Bayt

Çevrimiçi sürüm

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

Çift değer içermeyen 80 Bayt

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

1

Haskell, 39 bayt

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

Kullanım örneği: 4 # "ABCDEF"-> ["ABCD","BCDE","CDEF"]. Çevrimiçi deneyin!

nGirdi dizisinin ilk karakterlerini tutan basit bir özyineleme , uzunluğu en az olmadıkça dizenin kuyruğuyla devam eder n.


1

Microsoft SQL Server, 199 bayt

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

Kontrol et.



1

Yığılmış , 7 bayt

infixes

Çevrimiçi deneyin!

Oldukça standart. Bu yerleşik olmadan, 20 bayt olur:

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

Hangisi:

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

Ruby, 48 46 bayt

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

Belirli bir hile yoktur, sadece gerekli altlığı her geçerli başlangıç ​​noktasından çeken bir işlevi tanımlayan bir stab-lambdadır.

İki bayt kurtardı, çünkü lambdayı saklamak için bir ihtiyaç yok gibi görünüyor.


1

V , 16 bayt

òÀ|ly0Ïp
"_xòkVp

Çok iyi golf oynamam Korkuyor, "k> len (str) dizesini sil" ile mücadele ediyorum. Girdi dosyada, k bir argümandır. Açıklamadan önce Golf

Çevrimiçi deneyin!


K> len (str) vakasını ele almaya çalışmazsan ne olur?
Adám

Kullandığım yönteme bağlı olarak (özellikle bunlarda) dizeyi olduğu gibi bırakıyor
nmjcman101

1

Standart ML (mosml), 109 65 61 bayt

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

Bir sayı ve karakter listesi alır (SML dünyasında dizelere oldukça yaygın bir alternatif). (Gerçekten elbette tüm listelerinde çalışır.)

Kullanımı:

- 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

Değişiklikler:

  • Doğru, standart bir kütüphane var .. (-44 bytes)
  • Karşılaştırma yapıldı ve nil önerildiği gibi [] olarak değiştirildi (-4 bayt)

1
Sen değiştirerek byte kaydedebilirsiniz if length(x)<n theniçin if n>length(x)then. Bununla birlikte, SML'nin karakter dizileriyle başa çıkması mükemmel bir şekilde mümkün olduğundan explode, giriş dizgisine zaten uygulanması gerekebileceğinden emin değilim .
Laikoni

Ayrıca then nil elsekısaltılabilir then[]else.
Laikoni

@Likonik ya da emin değilim, ama ¯ \ _ (ツ) _ / ¯
L3viathan

Bazı kütüphane fonksiyonlarını kullanarak karakter listeleri yerine dizelerle uğraşan 68 baytlık bir versiyonum var . Ayrıca yaklaşımınız 54 bayt kısaltılabilir: fun f$n=if n>length$then[]else List.take($,n)::f(tl$)n.
Laikoni

1

JavaScript (Firefox 30-57), 51 bayt

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

ES6'da 64 bayt:

(s,n,t=s.slice(0,--n))=>[...s.slice(n)].map(c=>(t+=c).slice(~n))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.