Rosetta Stone Challenge: การแม็ปยีน


11

เป้าหมายของการท้าทาย Rosetta Stone คือการเขียนวิธีแก้ปัญหาในภาษาต่างๆให้ได้มากที่สุด แสดงการเขียนโปรแกรมได้หลายภาษาของคุณ!

ความท้าทาย

ความท้าทายของคุณคือการใช้โปรแกรมที่จะทำแผนที่ยีนโดยใช้ความถี่ข้ามมากกว่าที่เป็นหลายภาษาการเขียนโปรแกรมที่เป็นไปได้ คุณได้รับอนุญาตให้ใช้ฟังก์ชั่นไลบรารีมาตรฐานทุกประเภทที่ภาษาของคุณมีเนื่องจากนี่เป็นการนำเสนอภาษาเป็นส่วนใหญ่

"การแม็ปยีนคืออะไร"

การทำแผนที่ยีนเป็นกระบวนการของการค้นหาตำแหน่งสัมพัทธ์ของยีนในโครโมโซม สิ่งนี้ทำได้โดยการวัดความถี่การข้ามผ่านของคู่ของยีนเท่ากับร้อยละของลูกหลานที่คู่นั้นไม่ได้รับการถ่ายทอดร่วมกัน ระยะทางวัดในหน่วยแผนที่โดยมีหนึ่งหน่วยแผนที่เท่ากับหนึ่งเปอร์เซ็นต์ของการข้ามผ่าน ตัวอย่างเช่นหากยีน C & D มีความถี่ข้าม 11% แล้วยีน C คือระยะทาง 11 หน่วยแผนที่อยู่ห่างจากยีน D

การทำแผนที่ยีนจะดำเนินการกับยีนหลายคู่เพื่อกำหนดลำดับญาติของพวกเขา ตัวอย่างเช่นข้อมูล(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

สิ่งนี้ยังไม่ใช่ข้อกำหนดที่เข้มงวดอย่างสมบูรณ์ ตัวอย่างเช่นคุณสามารถใช้สิ่งอื่นนอกเหนือจากช่วงเวลาเช่นเครื่องหมายจุลภาคหรือช่องว่าง

เกณฑ์การชนะอย่างมีวัตถุประสงค์

สำหรับเกณฑ์การชนะอย่างมีวัตถุประสงค์นี่คือ: แต่ละภาษาเป็นการแข่งขันแยกกันว่าใครสามารถเขียนผลงานที่สั้นที่สุด แต่ผู้ชนะโดยรวมจะเป็นคนที่ชนะการแข่งขันย่อยมากที่สุดเหล่านี้ ซึ่งหมายความว่าบุคคลที่ตอบคำถามในภาษาแปลก ๆ หลาย ๆ แห่งจะได้รับการพิจารณาเป็นพิเศษ Code-golf ส่วนใหญ่เป็น tiebreaker เมื่อมีวิธีแก้ปัญหามากกว่าหนึ่งภาษา: บุคคลที่มีโปรแกรมสั้นที่สุดจะได้รับเครดิตสำหรับภาษานั้น

กฎข้อ จำกัด และหมายเหตุ

โปรแกรมของคุณสามารถเขียนในภาษาใด ๆ ที่มีอยู่ก่อนวันที่ 20 ธันวาคม 2013 ฉันจะต้องพึ่งพาชุมชนเพื่อตรวจสอบคำตอบบางอย่างที่เขียนในภาษาที่แปลกประหลาด / ลึกลับมากกว่าเนื่องจากฉันไม่สามารถทดสอบได้ พวกเขา


กระดานแต้มนำปัจจุบัน

ส่วนนี้จะได้รับการปรับปรุงเป็นระยะเพื่อแสดงจำนวนภาษาและผู้ที่เป็นผู้นำในแต่ละภาษา

  • AutoHotkey (632) - Avi
  • dj (579) - รูบิค

อันดับผู้ใช้ปัจจุบัน

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

เราควรรวมรหัสเพื่ออ่านอินพุตหรือไม่ หรือเราควรสมมติว่าอินพุตถูกส่งผ่านเป็นอาร์กิวเมนต์แรกของฟังก์ชัน?
รองเท้า

@ Jeffefrey ฉันคิดว่าอย่างใดอย่างหนึ่งเป็นเรื่องปกติ
PhiNotPi

.. ลีดเดอร์บอร์ด :-)
Avi

1
ขอบเขตการป้อนข้อมูลคืออะไร? ไม่มากนักnแต่โดยหลักแล้วขอบเขตสำหรับการข้ามผ่านความถี่ (ระยะทาง) เราสามารถสรุปได้ว่ามันจะถูกพูดน้อยกว่า1000?
rubik

@PhiNotPi: คุณสามารถเพิ่มกรณีทดสอบอีกสองสามข้อได้ไหม ฉันเล่นจนจบแล้วและต้องการทดสอบมากกว่านี้
บิค

คำตอบ:


2

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

รหัสสามารถย่อให้สั้นลงได้โดยเปลี่ยนชื่อ vars ทั้งหมดเป็น 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! นี่คือรหัสกอล์ฟดังนั้นโปรดแสดงความพยายามในการแก้ปัญหาด้วยจำนวนรหัสน้อยที่สุด สำหรับการเริ่มต้นคุณสามารถลบช่องว่างที่ไม่จำเป็นทั้งหมดออกและใช้ชื่อตัวแปร, ตัวอักษร struct และ function โปรดระบุภาษาและจำนวนไบต์ทั้งหมดที่ด้านบนของคำตอบของคุณ
Martin Ender
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.