すべてのk-mer / n-gram


21

イントロ

私たちは持っていたヒストグラムカウントを、それらのすべてをリストではありません。

毎年、Dyalog Ltd.は学生コンテストを開催しています。そこの課題は、優れた APLコードを書くことです。これは、今年の6番目の問題の言語に依存しない版です。

コンテストの元の著者からこのチャレンジをここに投稿する明示的な許可があります。提供されたリンクに従って作成者に連絡することにより、気軽に確認してください

問題

k-merという用語は、通常、文字列に含まれる長さkのすべての可能な部分文字列を指します。計算ゲノミクスでは、k-merは、DNAシーケンスで取得した読み取りから(長さkの)すべての可能なサブシーケンスを指します。文字列とk(部分文字列の長さ)を取り、元の文字列のk-merのベクトルを返す/出力する関数/プログラムを作成します。

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

k >文字列の長さ?戻り何/空の結果:
[4,"AC"][]または""または[""]


4
出力の順序は重要ですか?部分文字列が複数回発生する場合、出力で繰り返す必要がありますか?
-feersum

1
このように、文字列の配列の代わりに改行で区切られた必要な部分文字列の文字列を返すことはできますか?
リーキー修道女

以下のような文字の配列として文字列(5月我々はまた、入力と出力['A', 'T', 'C', 'G']の代わりに"ATCG"
アドナン・

Dyalog APLの回答は、このPPCGチャレンジで許可されていますか(チャレンジはDyalogによってホストされているため)?
クリティキシリソス

1
@feersum順序が重要であり、繰り返しを繰り返す必要があります。これはスライディングウィンドウのようなものです。
アダム

回答:


15

ゼリー、1 バイト

Jellyには、まさにこの操作のためのシングルバイトのダイアディックアトムがあります。

オンラインでお試しください!(フッターは、結果のリストを改行で分割し、不明瞭な表現が印刷されるのを防ぎます。)


1
どういうわけかOPは...知られている必要があります
漏れ修道女

1
@LeakyNun私は実際にはしませんでした。
アダム

8

オクターブ、28バイト

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

オンラインでお試しください!

k>文字列の長さはOctave 4.2.1-windowsで機能しますが、tio(Octave 4.0.3)では機能しません。

連続した要素の数値インデックスを作成し、それによって文字列にインデックスを付けます。

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


7

C(POSIX上のGCC)、67 66 63バイト

@LeakyNunのおかげで-3バイト!

f(i,s,j)char*s;{for(;j+i<=strlen(s);puts(""))write(1,s+j++,i);}

オンラインでお試しください!


あなたが必要とは思わないj=0
リーキー修道女

@LeakyNun関数は再利用可能でなければなりません。オンラインでお試しください!vs オンラインで試してみてください!
ベットセグ

けれども私が行う場合は、この ...
betseg

1
あなたは置き換えることができますj+i<=strlen(s)だけでs[j+i]
KritixiのLithos


5

Pythonの3 47の45 42バイト

ovsのおかげで-3バイト(Python 3のアンパックを使用a[n-1:]して末尾で再利用します。)

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

文字列、aおよびスライスの長さを取り、スライスnのリストまたは空の文字列を返す再帰関数。

a[n-1:]n-1 番目(0インデックス)の要素から現在の文字列のスライスを取り、十分な要素が残っているかどうかをテストします(Pythonでは空の文字列はfalseyです)-これは同等のものよりも短いですlen(a)>=n

  • リストが構築されるに十分な要素がある場合、[...]最初とn列の要素a[:n]、及び、再度関数を呼び出すの解凍結果*f(...)入力電流のデキューバージョンで、(最初の要素無し)a[1:]

  • 十分な要素がないa[n-1:]場合、返されるときに再帰の末尾に到達します(この場合は空の文字列)。

オンラインでお試しください!


Python 2または3の場合は45

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バイト(Python 3)TIO
ovs

@ovs、非常に素晴らしい、これが受け入れられるかどうか尋ねました(空の結果は文字列であり、空でない結果はリストであるため)。
ジョナサンアラン

4

J、2バイト

,\

完全なプログラムではなく、演算子を備えた機能です。

次のように呼び出します:

echo 4 ,\ 'ATCGAAGGTCGT'

オンラインでお試しください!

使い方

演算子(「接続詞」と呼ばれる)\(「infix」という名前)は、そのように使用されます

(x u\ y)uリストの連続する部分に動詞を適用しますy(挿入語と呼ばれます)。

(「動詞」と呼ばれる)機能u、この場合には、関数である,、単純な「あるAPPEND」機能:

の項目とxそれに続く項目を含む配列を作成しますy


3

Mathematica、21バイト

##~StringPartition~1&

匿名関数。入力として文字列と数字を(この順序で)受け取り、出力として文字列のリストを返します。


3

R、65 61バイト

-MickyTのおかげで2バイト

-2バイト、インデックス付けを変更して

無名関数を返します。

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

substringインデックスを巡回し(substrどちらともしない)、開始インデックスが1未満の場合はデフォルトで1代わりに空の文字列をチェックして返します。

x:n-n+1合計/差分よりも優先される1:(x-n+1)ため、:

オンラインでお試しください!


function(s,n,x=nchar(s))if で数バイト節約できます(n>x,'',substring(s,1:(x-n+1),n:x))
-MickyT

@MickyT、ありがとう!また、インデックスの計算を変更することでいくつかのバイトを削除できることに気付きました
ジュゼッペ


2

クラゲ、7バイト

p
_I
\i

オンラインでお試しください!

使い方

線形:でp(\(I,i))、where pはprintであり\、必要な部分文字列を取得します。

Iは生の最初の入力iで、評価された2番目の入力です。

Jellyfishでは、すべての関数と演算子は2つの引数を取得します。1つは右から、もう1つは下からです。ここで、関数pはの出力から引数を取得します_。これは、演算子\を使用してサブストリングを取得する場合に必要です。



2

Java(OpenJDK 8)、92バイト

void f(String s,int n){for(int i=n;i<=s.length();)System.out.println(s.substring(i-n,i++));}

オンラインでお試しください!



1
@KevinCruijssen私は答えを変えました。
リーキー修道女

2

Clojure、19バイト

まあこれは便利です。

#(partition % 1 %2)

例:

(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

網膜41 38バイト

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

オンラインでお試しください!

文字列を取得し、個別の行にカウントします。最初の2行はカウントを10進数から単項に変換するために使用されるため、単項入力が受け入れられる場合、バイトカウントは34 31に削減されます。編集:@FryAmTheEggmanのおかげで3バイト保存されました。または、必要に応じて、文字列内の改行を処理する48バイトバージョンですが、混乱を招く出力が生成されます。

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

@KritixiLithosあなたのソリューションがどのようにカウントを考慮に入れているかわかりません...-
ニール

ああ、申し訳ありませんが、私はちょうど脳のおならを持っていました> _ <
Kritixi Lithos

文字列に改行を含めることができる場合、私はあなたが変えることができると思うので、これは必ずしも、動作しません(?!)
FryAmTheEggman

2

画像パッケージ付きオクターブ、29バイト

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

オンラインでお試しください!

説明

この関数im2col(m,b)は行列を受け取り、そこからmサイズのブロックを抽出bし、列として配置します。デフォルトでは、ブロックはスライドします(個別ではありません)。ここで、行列mは入力文字列のASCIIコードの行ベクトルでありs(これは+s、標準よりも短いとして行われますdouble(s))、サイズb[1 n]n要素のです。

結果は転置され(transpose 'より短い複素共役transposeを使用 .')、列を行に変換し、次にchar([... '']標準より短いchar(...))に変換されます。



1

Python 3、49バイト

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

オンラインでお試しください!

短くはありませんが、非再帰的なソリューション。

Python 2と互換性があります。


他の場所をf=使用しないため、ドロップして2バイトを節約できfます。デフォルトでは、宣言されたばかりで使用されていない関数には名前を付けないでおくことができます。
ミスターXcoder


1

Haskell、39バイト

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

使用例:4 # "ABCDEF"-> ["ABCD","BCDE","CDEF"]オンラインでお試しください!

n入力文字列の最初の文字を保持し、その長さが未満でない限り文字列の末尾に続く単純な再帰n







1

ルビー、48 46バイト

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

特定のトリックはありません。それぞれの有効な開始点から必要なサブストリングを引き出す関数を定義するstabby-lambdaだけです。

ラムダを保存する必要がないように見えるため、2バイトを節約しました。


1

V、16バイト

òÀ|ly0Ïp
"_xòkVp

「k> len(str)の場合に文字列を削除する」ことに苦労して、ひどくよくゴルフをしていません。入力はファイル内にあり、kは引数です。説明前のゴルフ

オンラインでお試しください!


k> len(str)のケースを処理しようとしないとどうなりますか?
アダム

使用する方法(特にこの方法)に応じて、文字列をそのまま残します
nmjcman101

1

標準ML(mosml)、109 65 61バイト

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

数字と文字のリストを取ります(SMLの世界では文字列に代わる一般的な選択肢です)。(もちろん、すべてのリストで動作します。)

使用法:

- 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

変更ログ:

  • 右、標準ライブラリがあります。(-44バイト)
  • 提案どおりに比較とnilを[]に変更します(-4バイト)

1
に変更if length(x)<n thenすると、バイトを保存できますif n>length(x)then。ただし、SMLで文字列を処理することは完全に可能であるためexplode、入力文字列に既に適用されている必要があるかどうかはわかりません。
ライコニ

then nil elseに短縮することもできますthen[]else
ライコニ

@Laikoniどちらでもないが、¯\ _(ツ)_ /
¯– L3viathan

他のいくつかのライブラリ関数を使用して、charリストの代わりに文字列を扱う68バイトバージョンを入手しました。また、アプローチは54バイトに短縮できますfun f$n=if n>length$then[]else List.take($,n)::f(tl$)n
ライコニ

1

JavaScript(Firefox 30-57)、51バイト

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

ES6の64バイト:

(s,n,t=s.slice(0,--n))=>[...s.slice(n)].map(c=>(t+=c).slice(~n))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.