Rosetta Stone Challenge : 유전자 매핑


11

Rosetta Stone Challenge의 목표는 가능한 한 많은 언어로 솔루션을 작성하는 것입니다. 다국어 프로그래밍을 과시하십시오!

도전

가능한 많은 프로그래밍 언어로 교차 주파수를 사용하여 일부 유전자를 매핑하는 프로그램을 구현해야 합니다 . 대부분 언어 쇼케이스이기 때문에 언어에있는 모든 종류의 표준 라이브러리 함수를 사용할 수 있습니다.

"유전자 매핑"이란 무엇입니까?

유전자 매핑은 염색체에서 유전자의 상대적 위치를 찾는 과정입니다. 이것은 유전자 쌍의 교차 주파수를 측정하여 이루어지며, 그 쌍이 함께 유전 되지 않는 자손의 백분율과 같습니다 . 거리는 교차하는 비율이 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그 뒤에 유전자 목록 (대문자)이옵니다. 그러면 n세 개의 데이터가 생성됩니다. 각 세트는 한 쌍의 유전자와 그 교차 주파수 (거리)로 구성됩니다.

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

이것은 또한 완전히 엄격한 요구 사항이 아닙니다. 예를 들어 쉼표 나 공백과 같이 마침표 이외의 다른 것을 사용할 수 있습니다.

객관적인 승리 기준

객관적인 승리 기준은 다음과 같습니다. 각 언어는 가장 짧은 참가작을 작성할 수있는 사람에 대한 별도의 경쟁이지만 전체 우승자는 이러한 하위 경쟁을 가장 많이이기는 사람이됩니다. 이것은 많은 다른 언어로 대답하는 사람이 이점을 얻을 수 있음을 의미합니다. 코드 골프는 대부분 하나의 언어로 된 솔루션이있을 때 가장 큰 걸림돌입니다. 가장 짧은 프로그램을 가진 사람은 그 언어에 대한 학점을 얻습니다.

규칙, 제한 및 참고

귀하의 프로그램은 2013 년 12 월 20 일 이전에 존재했던 모든 언어로 작성 될 수 있습니다. 또한 테스트가 불가능하기 때문에 커뮤니티에 의존하여 좀 더 흔하지 않은 / 비언어적 언어로 작성된 일부 응답의 유효성을 검증해야합니다. 그들.


현재 리더 보드

이 섹션은 정기적으로 업데이트되어 언어의 수와 언어를 구사하는 사람을 보여줍니다.

  • 오토 핫키 (632)-Avi
  • 디제이 (579)-매직

현재 사용자 순위

  1. Avi (1) : 오토 핫키 (632)
  2. 루빅 (1) : dj (579)

입력을 읽는 코드를 포함시켜야합니까? 아니면 입력이 함수의 첫 번째 인수로 전달되었다고 가정해야합니까?
구두

@ Jefffrey 나는 어느 쪽이든 괜찮다고 생각합니다.
PhiNotPi

.. 리더 보드? :-)
Avi

1
입력 범위는 무엇입니까? 그리 많지 n는 않지만 주로 교차 주파수 (거리)에 대한 경계입니다. 항상 그렇지 않다고 가정 할 수 있습니까 1000?
rubik

@PhiNotPi : 몇 가지 테스트 사례를 더 제공 할 수 있습니까? 나는 거의 내 것을 끝내고 더 테스트하고 싶습니다.
rubik

답변:


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,".")
}

모든 var의 이름을 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

파이썬 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

(카운팅에 대해 잘 모르겠습니다. 문자 수로 온라인으로 게시합니다)

알고리즘의 아이디어는 꽤 나쁘지만 짧습니다. 모든 제약 조건을 충족 할 때까지 Symbol의 모든 위치를 임의로 시도하십시오. 예를 들어 입력에 공백이 있습니다.

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 바이트

파이썬이 들어옵니다.

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에 오신 것을 환영합니다! 이것은 코드 골프이므로 최소한의 코드로 문제를 해결하기 위해 노력하십시오. 시작하려면 불필요한 공백을 모두 제거하고 단일 문자 변수, 구조체 및 함수 이름을 사용할 수 있습니다. 답변 상단에 언어와 총 바이트 수를 포함하십시오.
Martin Ender
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.