ロゼッタストーンチャレンジ:遺伝子マッピング


11

Rosetta Stone Challengeの目標は、可能な限り多くの言語でソリューションを作成することです。プログラミングの多言語性を自慢しましょう!

チャレンジ

あなたの課題は、できるだけ多くのプログラミング言語で、クロスオーバー周波数を使用していくつかの遺伝子をマッピングするプログラムを実装することです。これは主に言語のショーケースであるため、言語が持つあらゆる種類の標準ライブラリ関数を使用できます。

「遺伝子マッピング」とは何ですか?

遺伝子マッピングは、染色体上の遺伝子の相対的な位置を特定するプロセスです。これは、ペアが一緒に継承されない子孫の割合に等しい遺伝子のペアの交差頻度を測定することによって行われます。距離はマップ単位で測定され、1つのマップ単位は交差の1%に相当します。たとえば、遺伝子CとDの交差頻度が11%の場合、遺伝子Cは遺伝子Dから11マップユニット離れた距離にあります。

遺伝子のマッピングは、遺伝子の複数のペアを使用して実行され、相対的な順序が決定されます。たとえば、データ(A,B,12) (D,B,7) (A,D,5) (D,H,2) (H,B,9)は次のマップを生成します。

A..H.D......B

これB......D.H..Aも有効なマップであることに気付いたかもしれません。これは、ミラーの反対側を区別することができないためです。プログラムは出力するものを選択できます。入力には可能なすべてのペアが含まれるわけではありませんが、マップ全体を再構築するのに十分な情報が常に存在します(したがって、有効な出力が2つを超えることはありません)。さらに、数値は常に(実際の生物学とは異なり)うまくいきます。つまり、のようなものはありません(A,B,3) (B,C,4) (A,C,13)

入力

入力は数字で始まり、nその後に遺伝子のリスト(大文字)が続きます。その後、n3つのデータが存在します。各セットは、1組の遺伝子とそれらの交差周波数(距離)で構成されます。

3,P,H,I
P,H,3
H,I,1
P,I,4

7,A,B,G,Q,U
B,Q,4
A,B,10
G,U,13
Q,U,10
A,G,9
G,Q,3
A,Q,6

入力は厳密に定義されていません。これは、異なる言語では実行可能なものに制限があるためです。たとえば、区切り文字をコンマと改行以外に変更できます。入力フォーマットは主にあなた次第です。

出力

出力は、遺伝子マップのレンディションになります。距離が正確に描かれるように、ピリオドで区切られた遺伝子(大文字)で構成されます。上記の例の出力は次のとおりです。

P..HI  *or*  IH..P

BG..Q.....A...U  *or*  U...A.....Q..GB

これも完全に厳格な要件ではありません。たとえば、コンマやスペースなど、ピリオド以外のものを使用できます。

客観的な勝利基準

客観的な勝利基準については、次のとおりです。各言語は、最短のエントリを書くことができる人については個別の競争ですが、全体的な勝者は、これらのサブ競争のほとんどに勝った人になります。これは、多くの一般的でない言語で回答する人が有利になることを意味します。Code-golfは、言語に複数の解決策がある場合の大部分のタイブレーカーです。最短のプログラムを持っている人は、その言語の信用を得ます。

ルール、制限、および注意

あなたのプログラムは2013年12月20日より前に存在した任意の言語で書くことができます。また、私はテストすることができそうにないので、より珍しい/難解な言語で書かれたいくつかの応答を検証するためにコミュニティに頼る必要がありますそれら。


現在のリーダーボード

このセクションは定期的に更新され、言語の数とそれぞれの言語のリーダーを示します。

  • AutoHotkey(632)-Avi
  • dj(579)-ルービック

現在のユーザーランキング

  1. Avi(1):AutoHotkey(632)
  2. rubik(1):dj(579)

入力を読み取るコードを含める必要がありますか?または、入力が関数の最初の引数として渡されると仮定する必要がありますか?

@Jefffreyどちらかでいいと思う。
PhiNotPi

..リーダーボード?:
アビ14年

1
入力範囲とは何ですか?それほど多くnはありませんが、主に交差周波数(距離)の境界です。常に、たとえば以下になると仮定できます1000か?
ルービック

@PhiNotPi:さらにいくつかのテストケースを提供できますか?私はほとんど私のものを終えました、そして、私はそれをもっとテストしたいです。
ルービック

回答:


2

オートホットキー(632)

f(i){
o:={},f:={},n:=0
loop,parse,i,`n
{
a:=A_LoopField
if A_index!=1
{
@:=Substr(a,1,1),#:=Substr(a,3,1),n+=($:=Substr(a,5))
if !IsObject(o[@])
o[@]:={}
if !IsObject(o[#])
o[#]:={}
o[@][#]:=o[#][@]:=$
}
}
f[n+1]:=@,f[@]:=n+1,a:=""
while !a
{
a:=0
for k,v in o
{
if !f[k]
{
c1:=c2:=s:=0
for k1,v1 in v
{
if f[k1]
if s
{
if (r1==f[k1]-v1)or(r1==f[k1]+v1)
c1:=r1
else r1:=c1:=""
if (r2==f[k1]-v1)or(r2==f[k1]+v1)
c2:=r2
else r2:=c2:=""
}
else
c1:=r1:=f[k1]+v1,c2:=r2:=f[k1]-v1,s:=1
}
if c1
f[c1]:=k,f[k]:=c1,a:=1
else if c2
f[c2]:=k,f[k]:=c2,a:=1
}
} 
}
loop % 2*n+1
{
v:=f[A_index]
if v
z:=1
r.=z?(!v?".":v):v
}
return Rtrim(r,".")
}

すべての変数の名前を1文字に変更することで、コードをさらに短縮できます。その後、約610文字になります。

テストケース

v := "
(7,A,B,G,Q,U
B,Q,4
A,B,10
G,U,13
Q,U,10
A,G,9
G,Q,3
A,Q,6 
)"

msgbox % f(v)
msgbox % f("3,P,H,I`nP,H,3`nH,I,1`nP,I,4")

1

Python 311

import sys,random
d=sys.stdin.readlines()
u=[]
r=g=0
m={}
l=d[0].split()[1:]
for a in l:m[a]=g;g+=1
for v in d[1:]:i=v.split();u+=[i];r+=int(i[2])
j=len(l)
y=range(j)
while any(abs(y[m[t]]-y[m[w]])!=int(p) for t,w,p in u):y=random.sample(range(r),j)
o=["."]*r
for a in m:o[y[m[a]]]=a
print "".join(o).strip(".")

私の最初のコードゴルフ:D

(カウントについては定かではありませんが、文字数でオンラインで送信するだけです)

アルゴリズムのアイデアはかなり悪いですが、短いです。すべての制約を満たすまで、シンボルのすべての位置をランダムに試してください。入力には、たとえば空白が含まれます

3 P H I
P H 3
H I 1
P I 4

コンソールでCTRL + Dを押してから、読み取りを終了します。

以下は、区切り文字としてまだ「、」を使用している元のコードです。

import sys, random
#data = sys.stdin.readlines()
data = [
"3,P,H,I",
"P,H,3",
"H,I,1",
"P,I,4"
]
container = []
max_range = 0
map = {}
map_counter = 0

line_split = data[0].split(',')[1:]
count = len(line_split) # Number of genes
for symbol in line_split:
    map[symbol] = map_counter
    map_counter += 1

for line in data[1:]:
    line_split = line.split(',')
    container.append(line.split(','))
    max_range += int(line_split[2])

restart = True
while restart == True:
    positions = random.sample(range(max_range), count) # Since this loop will take like forever, but some day it will produce the correct positions
    restart = False
    for symbol1, symbol2, distance in container:
        if abs(positions[map[symbol1]] - positions[map[symbol2]]) != int(distance):
            restart = True
            break

output = ["."] * max_range
for symbol in map:
    output[positions[map[symbol]]] = symbol
print "".join(output).strip(".") # Strip . to make it more pretty

0

dg- 717 579バイト

Pythonが登場します。

import '/sys'
w,o=list,tuple
p=g a b m->
 b in g=>a,b=b,a
 i,l,k=g.index a,w$g,w$g
 l!!(i+m),k!!(i-m)=b,b
 g!!(i+m)=='.'=>yield$o$l
 g!!(i-m)=='.'=>yield$o$k
g=t->
 d=sorted key:(i->snd i)$map((a,b,i)->((a,b),int i))$filter fst$map(i->i.split ',')$t.split '\n'
 (a,b),i=d.pop!
 g=w$('.',)*i*4
 g!!i,g!!(i+i)=a,b
 s=set'$o g
 while d=>
  d.sort key:((k,v)->set k&(set$fst$w s))
  n,(a,b),i=set! :+d.pop!
  for r in s=>
   if(a in r and b in r=>i==abs(r.index a-r.index b)=>n.add r)(1=>n.update$p r a b i)
   s = n
 '\n'.join$map(l->(''.join l).strip '.')s
print$g sys.stdin.read!

例:

$ echo """P,H,3
H,I,1
P,I,4""" | dg dna.dg
P..HI
$ echo """B,Q,4
A,B,10
G,U,13              
Q,U,10
A,G,9
G,Q,3
A,Q,6""" | dg dna.dg
BG..Q.....A...U

0
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <malloc.h>

struct Gene
{
    char a1 , a2 ;
    int d ;
};
typedef struct Gene gene ;

struct Set
{
    int appr_id ;
    char CMN_char ;
};
typedef struct Set set ;

gene *stack;
int cp_id1 , cp_id2 , N=0 , cid , *used , n ;
char ucmn_char , *cmp1 , *cmp2 , *base , ep[15] ;                       
set ap_set ;


void randomize(void)
{   int i;
    Set temp;
    for(i=0;i<(n-1);i++)
    {
        temp=stack[i];
        stack[i]=stack[i+1];
        stack[i+1]=temp;
    }

    return;

}
void populate_ep ( char ucmn_char )
{
    int i;
    for ( i=0 ; ep[i] != '\0' ; i ++ );
        ep[ i ] = ucmn_char ;
}

set find_appr ( void )
{
    int i , j ;
    set s ;
    for ( i = 0 ; i < n ; i++ )
    {
        if ( used[ i ] == 1 )
            continue ;
        else
        {
            for ( j = 0 ; ep[ j ] != '\0' ; j++ )
            {
                if ( ep[ j ] == stack[ i ].a1 || ep[ j ] == stack[ i ].a2 )
                {
                    s.appr_id = i ;
                    s.CMN_char = ep[ j ] ;
                    return s ;
                }
            }
        }
    }
}

void destroy ( int id )
{
    used[ id ] = 1 ;
}

int get_center_id ( char a )
{
    int i ;
    for ( i = 0 ; i < N * 2 ; i++ )
        if ( base[ i ] == a )
            return i ;
}

int get_comparer ( void )
{
    int i , j , k ;
    for ( i = 0 ; i < n ; i ++ )
    {
        if ( used[ i ] == 0 )
        for ( j = 0 ; ep[ j ] != '\0' ; j ++ )
            if ( stack[ i ].a1 == ep[ j ])
                for ( k = 0 ; k < 15 ; k ++ )
                    if ( stack[ i ].a2 == ep[ k ] )
                        return i ;
    }
    printf ( "\nWrong set of genes....\n" ) ;
    exit ( 0 ) ;
}

void compare_and_merge ( int cid, int cp_id1, int cp_id2 )
{
    int base_cp_id , i ;
    char temp = ( ucmn_char == stack[ cid ].a1 ) ? stack[ cid ].a2 : stack[ cid ].a1 ;
    for ( i = 0 ; i < N * 2 ; i ++ )
        if ( base[ i ] == temp )
            base_cp_id = i ;
    if ( stack[ cid ].d == ( sqrt ( pow ( ( cp_id1 - base_cp_id ) , 2 ) ) ) )
    {   
        base[ cp_id1 ] = cmp1[ cp_id1 ] ;
        return ;
    }
    else
    {
        base[ cp_id2 ] = cmp2[ cp_id2 ] ;
        return ;
    }
}

void show_stack ( void )
{
    int i ;
    printf ( "The gene sets you entered are: \n" ) ;
    printf ( "____________\n" ) ;
    for ( i = 0 ; i < n ; i ++ )
        if ( used[ i ] == 0 )
            printf ( "%c %c %d\n" , stack[i].a1, stack[i].a2, stack[i].d ) ;
    printf ( "____________\n" ) ;
}

int main ( void )
{
    printf ( "Enter number of gene sets: " ) ;
    scanf ( "%d" , &n ) ;
    stack = ( gene* ) calloc ( n , sizeof ( gene ) ) ;
    used = ( int* ) calloc ( n , sizeof ( int ) ) ;
    int i ;
    N = 0 ;
    for ( i = 0 ; i < n ; i ++ )
    {
        char y[ 2 ] ;
        scanf ( "%s" , y ) ;
        stack[ i ].a1 = y[ 0 ] ;
        scanf ( "%s" , y ) ;
        stack[ i ].a2 = y[ 0 ] ;
        scanf ( "%d" , &stack[ i ].d ) ;
        N += stack[ i ].d ;
        used[ i ] = 0 ;
        fflush ( stdin ) ;
    }   
    randomize();
    show_stack ( ) ;
    int ff ;
    strcpy ( ep , " " ) ;
    cmp1 = ( char* ) calloc ( N * 2 , sizeof ( char ) ) ;
    cmp2 = ( char* ) calloc ( N * 2 , sizeof ( char ) ) ;
    base = ( char* ) calloc ( N * 2 , sizeof ( char ) ) ;
    for ( i = 0 ; i < N * 2 ; i ++ )
        base[ i ] = cmp1[ i ] = cmp2[ i ] = '=' ;
    base[ N ] = stack[ 0 ].a1 ;
    base[ N + stack[ 0 ].d ] = stack[ 0 ].a2 ;
    destroy ( 0 ) ;
    ep[ 0 ] = stack[ 0 ].a1 ;
    ep[ 1 ] = stack[ 0 ].a2 ;
    for ( ff = 0 ; ff < n / 2  ; ff ++ )
    {
        ap_set = find_appr ( ) ;
        cmp1[ get_center_id ( ap_set.CMN_char ) ] = ap_set.CMN_char ;
        cmp2[ get_center_id ( ap_set.CMN_char ) ] = ap_set.CMN_char ;
        ucmn_char = ( stack[ ap_set.appr_id ].a1 == ap_set.CMN_char ) ? stack[ ap_set.appr_id ].a2 : stack[ ap_set.appr_id ].a1;
        cmp1[ cp_id1 = get_center_id ( ap_set.CMN_char ) + stack[ ap_set.appr_id ].d ] = ucmn_char ;
        cmp2[ cp_id2 = get_center_id ( ap_set.CMN_char ) - stack[ ap_set.appr_id ].d ] = ucmn_char ;
        populate_ep ( ucmn_char ) ;
        destroy ( ap_set.appr_id ) ;
        cid = get_comparer ( ) ;
        compare_and_merge ( cid , cp_id1 , cp_id2 ) ;
        destroy ( cid ) ;
    }
    int start , end ;
    for ( i = 0 ; i < N * 2 ; i ++ )
        if ( base[ i ] != '=' )
        {
            start = i ;
            break ;
        }
    for ( i = N * 2 - 1 ; i >= 0 ; i -- )
        if ( base[ i ] != '=' )
        {
            end = i ;
            break ;
        }
        for ( i = start ; i <= end ; i ++ )
            printf( "%c" , base[ i ] ) ;
    printf( "\n\n" ) ;
}

3
PPCGへようこそ!これはコードゴルフですので、最小限のコードで問題を解決するための努力を見せてください。まず、不要な空白をすべて削除し、1文字の変数、構造体、および関数名を使用できます。回答の上部に言語と合計バイト数も含めてください。
マーティンエンダー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.