Rosetta Stone Challenge: Gen Haritalaması


11

Rosetta Stone Challenge'ın hedefi mümkün olduğunca çok dilde çözüm yazmaktır. Programlama çokdilliliğinizi gösterin!

Meydan okuma

Zorluğunuz, çapraz genleri kullanarak bazı genleri mümkün olduğunca çok programlama dilinde eşleyecek bir program uygulamaktır . Çoğunlukla bir dil vitrini olduğundan, dilinizin sahip olduğu her türlü standart kitaplık işlevini kullanmanıza izin verilir.

"Gen haritalaması" nedir?

Gen haritalama, genlerin kromozomlar üzerindeki nispi pozisyonunun tespit edilmesi işlemidir. Bu, çiftin miras alınmadığı yavruların yüzdesine eşit olan gen çiftlerinin geçiş sıklığı ölçülerek yapılır . Mesafe, bir harita birimi kesişme yüzdesine eşit olan harita birimlerinde ölçülür . Örneğin, C ve D genleri% 11'lik bir geçiş frekansına sahipse, C geni, D geninden 11 harita birimi uzaklığıdır.

Gen haritalaması, nispi sıralarını belirlemek için birden fazla gen çifti ile gerçekleştirilir. Örneğin, veriler (A,B,12) (D,B,7) (A,D,5) (D,H,2) (H,B,9)aşağıdaki haritayı oluşturur:

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

Bunun B......D.H..Ageçerli bir harita olduğunu fark etmiş olabilirsiniz . Bu doğrudur, çünkü ayna karşıtlarını ayırt etmek mümkün değildir. Programınız hangisinin çıktı alınacağını seçebilir. Giriş mümkün olan her çifti içermese de, haritanın tamamını yeniden yapılandırmak için her zaman yeterli bilgi olacaktır (bu nedenle asla 2'den fazla geçerli çıkış olmayacaktır). Buna ek olarak, sayılar her zaman işe yarayacaktır (gerçek biyolojiden farklı olarak), yani benzer şeyleriniz olmayacaktır (A,B,3) (B,C,4) (A,C,13).

Giriş

Giriş bir sayı ve nardından bir gen listesi (büyük harfler) ile başlar. Bu durumda nüçüz üçlüsü olacaktır . Her küme bir çift genden ve bunların frekans (mesafe) üzerinden geçmesinden oluşacaktır.

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

Girdi katı bir şekilde tanımlanmamıştır, çünkü farklı diller mümkün olan şeyler üzerinde kısıtlamalara sahip olabilir. Örneğin, sınırlayıcıları virgül ve satırsonu dışında bir şeyle değiştirebilirsiniz. Girdi biçimlendirmesi büyük ölçüde size bağlıdır.

Çıktı

Çıktı, gen haritasının bir sunumu olacaktır. Mesafelerin doğru bir şekilde tasvir edilmesi için noktalarla aralıklı genlerden (büyük harfler) oluşacaktır. Yukarıdaki örneklerin çıktıları aşağıda verilmiştir.

P..HI  *or*  IH..P

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

Bu da tamamen katı bir gereklilik değildir. Örneğin, virgül veya boşluk gibi noktalardan başka bir şey kullanabilirsiniz.

Amaç Kazanma Kriteri

Nesnel bir kazanma ölçütüne gelince, işte: Her dil, en kısa girişi kimin yazabileceği konusunda ayrı bir yarışmadır, ancak genel kazanan, bu alt yarışmaların çoğunu kazanan kişi olacaktır. Bu, nadir olmayan birçok dilde cevap veren bir kişinin avantaj sağlayabileceği anlamına gelir. Code-golf çoğunlukla bir dilde birden fazla çözüm olduğunda bir çığır açıcıdır: en kısa programa sahip olan kişi bu dil için kredi alır.

Kurallar, Kısıtlamalar ve Notlar

Programınız 20 Aralık 2013'ten önce mevcut olan herhangi bir dilde yazılabilir. Ayrıca, daha nadir / ezoterik dillerin bazılarında yazılan bazı yanıtları doğrulamak için topluluğa güvenmek zorunda kalacağım, çünkü test edemiyorum onlar.


Mevcut Büyük Şerit

Bu bölüm, dillerin sayısını ve her birinin önde gelenlerini göstermek için periyodik olarak güncellenecektir.

  • Otomatik Kısayol Tuşu (632) - Avi
  • dj (579) - rubik

Mevcut Kullanıcı Sıralaması

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

Girişi okumak için kod eklememiz gerekir mi? Yoksa girdinin işlevin ilk argümanı olarak geçtiğini mi varsaymalıyız?
Ayakkabı

Sanırım ikisinden biri iyi.
PhiNotPi

.. büyük afiş? :-)
Avi

1
Girdi sınırları nelerdir? Çok fazla değil n, öncelikle frekans (mesafe) üzerinden geçiş için sınırlar. Her zaman, örneğin, daha az olacağını varsayabilir miyiz 1000?
rubik

@PhiNotPi: Birkaç test vakası daha sağlayabilir misiniz? Neredeyse benimkini bitirdim ve daha fazla test etmek istiyorum.
rubik

Yanıtlar:


2

Otomatik Kısayol tuşu (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,".")
}

Tüm isimler 1 karakter olarak yeniden adlandırılarak kod daha da kısaltılabilir. Bu durumda yaklaşık 610 karakter olmalıdır.

Test Durumları

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

İlk kod golfüm: D

(Sayımdan emin değilim, sadece bir karakter sayısında çevrimiçi olarak ilan ediyorum)

Algoritma fikri oldukça kötü, ama kısa. Tüm kısıtlamaları karşılayana kadar Semboller için tüm konumları rastgele deneyin. Girdi, örneğin boşlukla

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

Okumayı sonlandırmak için konsoldaki CTRL + D tuşlarına basın.

İşte sınırlayıcı olarak hala ',' kullanan orijinal kod.

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 bayt

Bir Python geliyor.

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!

Örnekler:

$ 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'ye Hoşgeldiniz! Bu kod golf, bu yüzden sorunu minimum miktarda kod çözmek için biraz çaba gösterin. Başlangıç ​​için tüm gereksiz boşlukları kaldırabilir ve tek harfli değişken, yapı ve işlev adları kullanabilirsiniz. Lütfen yanıtı dilinize ve toplam bayt sayısını da ekleyin.
Martin Ender
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.