Rosetta Stone Challenge: Gene Mapping

11

Tujuan dari Rosetta Stone Challenge adalah menulis solusi dalam bahasa sebanyak mungkin. Pamerkan multibahasa Anda dalam pemrograman!

Tantangan

Tantangan Anda adalah mengimplementasikan program yang akan memetakan beberapa gen menggunakan frekuensi cross-over, dalam sebanyak mungkin bahasa pemrograman . Anda diperbolehkan menggunakan segala jenis fungsi perpustakaan standar yang dimiliki bahasa Anda, karena ini sebagian besar adalah karya bahasa.

Apa itu "pemetaan gen?"

Pemetaan gen adalah proses menemukan posisi relatif gen pada kromosom. Ini dilakukan dengan mengukur frekuensi penyilangan pasangan gen, sama dengan persentase keturunan di mana pasangan tidak diwariskan bersama. Jarak diukur dalam unit peta dengan satu unit peta yang sama dengan satu persen persimpangan. Sebagai contoh, jika gen C & D memiliki frekuensi cross-over 11%, maka gen C adalah jarak 11 unit peta dari gen D.

Pemetaan gen dilakukan dengan beberapa pasang gen untuk menentukan urutan relatifnya. Misalnya, data (A,B,12) (D,B,7) (A,D,5) (D,H,2) (H,B,9)menghasilkan peta berikut:

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

Anda mungkin memperhatikan bahwa B......D.H..Aitu juga peta yang valid. Ini benar, karena tidak mungkin untuk membedakan antara cermin yang berlawanan. Program Anda dapat memilih mana yang akan di-output. Meskipun input mungkin tidak mencakup setiap pasangan yang memungkinkan, akan selalu ada informasi yang cukup untuk merekonstruksi seluruh peta (sehingga tidak akan ada lebih dari 2 output yang valid). Selain itu, angka-angkanya akan selalu berhasil (tidak seperti biologi yang sebenarnya), artinya Anda tidak akan memiliki barang seperti itu (A,B,3) (B,C,4) (A,C,13).

Memasukkan

Input akan dimulai dengan nomor yang ndiikuti oleh daftar gen (huruf besar). Kemudian akan ada nkembar tiga data. Setiap set akan terdiri dari sepasang gen dan frekuensi persilangannya (jarak).

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

Input tidak didefinisikan secara kaku, karena bahasa yang berbeda mungkin memiliki batasan pada apa yang layak. Misalnya, Anda dapat mengubah pembatas menjadi sesuatu selain koma dan baris baru. Pemformatan input sebagian besar terserah Anda.

Keluaran

Output akan menjadi rendition dari peta gen. Ini akan terdiri dari gen (huruf kapital) yang diberi spasi oleh periode sedemikian rupa sehingga jaraknya digambarkan secara akurat. Berikut adalah output untuk contoh-contoh di atas.

P..HI  *or*  IH..P

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

Ini juga bukan persyaratan yang sepenuhnya kaku. Misalnya Anda bisa menggunakan sesuatu selain titik, seperti koma atau spasi.

Kriteria Kemenangan yang Objektif

Adapun kriteria kemenangan yang objektif, ini dia: Setiap bahasa adalah kompetisi terpisah untuk siapa yang dapat menulis entri terpendek, tetapi pemenang keseluruhan adalah orang yang memenangkan sebagian besar sub-kompetisi ini. Ini berarti bahwa seseorang yang menjawab dalam banyak bahasa yang tidak biasa dapat memperoleh keuntungan. Code-golf sebagian besar tiebreak ketika ada lebih dari satu solusi dalam bahasa: orang dengan program terpendek mendapat pujian untuk bahasa itu.

Aturan, Batasan, dan Catatan

Program Anda dapat ditulis dalam bahasa apa pun yang ada sebelum 20 Desember 2013. Saya juga harus bergantung pada komunitas untuk memvalidasi beberapa tanggapan yang ditulis dalam beberapa bahasa yang lebih jarang / esoterik, karena saya tidak mungkin dapat menguji mereka.


Papan Peringkat Saat Ini

Bagian ini akan diperbarui secara berkala untuk menunjukkan jumlah bahasa dan siapa yang memimpin di masing-masing bahasa.

  • AutoHotkey (632) - Avi
  • dj (579) - rubik

Peringkat Pengguna Saat Ini

  1. Avi (1): AutoHotkey (632)
  2. rubik (1): dj (579)
PhiNotPi
sumber
Haruskah kita memasukkan kode untuk membaca input? Atau haruskah kita berasumsi bahwa input dilewatkan sebagai argumen pertama dari fungsi?
Sepatu
@ Jeffffrey Saya kira salah satu baik-baik saja.
PhiNotPi
.. papan peringkat? :-)
Avi
1
Apa batasan input? Tidak terlalu banyak n, tetapi terutama batas-batas untuk menyeberang frekuensi (jarak). Bisakah kita menganggap itu akan selalu, katakanlah, kurang dari itu 1000?
rubik
@PhiNotPi: dapatkah Anda memberikan beberapa kasus uji lagi? Saya hampir selesai dan saya ingin mengujinya lebih lanjut.
rubik

Jawaban:

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

Kode dapat lebih pendek dengan mengganti nama semua vars menjadi 1 karakter .. Itu harus sekitar 610 karakter.

Uji Kasus

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")
Avi
sumber
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(".")

Golf kode pertama saya: D

(Saya tidak yakin dengan penghitungan, saya hanya mempostingnya secara online dalam jumlah karakter)

Gagasan algoritme sangat buruk, tetapi singkat. Coba secara acak semua posisi untuk Simbol sampai mereka memenuhi semua kendala. Input dengan spasi putih misalnya

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

Tekan setelah itu CTRL + D di konsol untuk mengakhiri pembacaan.

Berikut adalah kode asli yang masih menggunakan ',' sebagai pembatas.

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
nvidia
sumber
0

dg - 717 579 byte

Satu Python masuk.

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!

Contoh:

$ 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
rubik
sumber
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" ) ;
}
Ankit Kumar
sumber
3
Selamat datang di PPCG! Ini adalah kode golf, jadi tolong tunjukkan upaya untuk memecahkan masalah dalam jumlah minimal kode. Sebagai permulaan, Anda bisa menghapus semua spasi kosong yang tidak perlu dan menggunakan variabel huruf tunggal, struct, dan nama fungsi. Harap sertakan juga bahasa dan jumlah byte total di bagian atas jawaban Anda.
Martin Ender