Rosetta Stone Challenge: Gene Mapping


11

L'obiettivo di una Rosetta Stone Challenge è scrivere soluzioni in quante più lingue possibili. Mostra il tuo multilinguismo di programmazione!

La sfida

La tua sfida è quella di implementare un programma che mapperà alcuni geni usando frequenze incrociate, nel maggior numero di linguaggi di programmazione possibile . Puoi usare qualsiasi tipo di funzione di libreria standard nella tua lingua, poiché questa è principalmente una vetrina linguistica.

Che cos'è la "mappatura genica?"

La mappatura genica è il processo di localizzazione della posizione relativa dei geni sui cromosomi. Questo viene fatto misurando la frequenza di incrocio tra coppie di geni, pari alla percentuale di progenie in cui quella coppia non è ereditata insieme. La distanza viene misurata in unità cartografiche con un'unità cartografica pari all'uno percento dell'incrocio. Ad esempio, se i geni C e D hanno una frequenza di incrocio dell'11%, allora il gene C è una distanza di 11 unità cartografiche dal gene D.

La mappatura genica viene eseguita con più coppie di geni per determinare il loro ordine relativo. Ad esempio, i dati (A,B,12) (D,B,7) (A,D,5) (D,H,2) (H,B,9)producono la seguente mappa:

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

Potresti aver notato che B......D.H..Aè anche una mappa valida. Questo è vero, perché non è possibile distinguere tra opposti speculari. Il tuo programma può scegliere quale produrre. Sebbene l'input possa non includere tutte le coppie possibili, ci saranno sempre informazioni sufficienti per ricostruire l'intera mappa (quindi non ci saranno mai più di 2 output validi). Inoltre, i numeri funzioneranno sempre (diversamente dalla biologia reale), il che significa che non avrai cose come (A,B,3) (B,C,4) (A,C,13).

Ingresso

L'input inizierà con un numero nseguito da un elenco di geni (lettere maiuscole). Ci saranno quindi ntriplette di dati. Ogni set sarà composto da una coppia di geni e dalla loro frequenza di attraversamento (distanza).

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

L'input non è definito rigidamente, perché lingue diverse possono avere restrizioni su ciò che è fattibile. Ad esempio, è possibile modificare i delimitatori in qualcosa di diverso da virgole e newline. La formattazione dell'input dipende in gran parte da te.

Produzione

L'output sarà una rappresentazione della mappa genica. Consisterà in geni (lettere maiuscole) distanziati da punti in modo tale che le distanze siano rappresentate accuratamente. Ecco le uscite per gli esempi sopra.

P..HI  *or*  IH..P

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

Anche questo non è un requisito completamente rigido. Ad esempio potresti usare qualcosa di diverso dai punti, come virgole o spazi.

Il criterio vincente dell'obiettivo

Per quanto riguarda un criterio obiettivo vincente, eccolo qui: ogni lingua è una competizione separata su chi può scrivere la voce più breve, ma il vincitore generale sarebbe la persona che vince la maggior parte di queste sotto-competizioni. Ciò significa che una persona che risponde in molte lingue non comuni può ottenere un vantaggio. Il code-golf è principalmente un tiebreak per quando c'è più di una soluzione in una lingua: la persona con il programma più corto ottiene credito per quella lingua.

Regole, restrizioni e note

Il tuo programma può essere scritto in qualsiasi lingua esistente prima del 20 dicembre 2013. Dovrò anche fare affidamento sulla comunità per convalidare alcune risposte scritte in alcune delle lingue più insolite / esoteriche, poiché è improbabile che io sia in grado di testare loro.


Classifica attuale

Questa sezione verrà periodicamente aggiornata per mostrare il numero di lingue e chi guida in ciascuna di esse.

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

Classifiche utente corrente

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

Dovremmo includere il codice per leggere l'input? O dovremmo solo supporre che l'input sia passato come primo argomento della funzione?
Scarpa

@Jefffrey Suppongo che uno vada bene.
PhiNotPi

.. la classifica? :-)
Avi

1
Quali sono i limiti di input? Non tanto n, ma soprattutto i limiti per l'attraversamento della frequenza (distanza). Possiamo supporre che sarà sempre, diciamo, inferiore a 1000?
rubik,

@PhiNotPi: puoi fornire un altro paio di casi di test? Ho quasi finito il mio e mi piacerebbe testarlo di più.
rubik,

Risposte:


2

Tasto di scelta automatica (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,".")
}

Il codice può essere abbreviato rinominando tutti i VAR con 1 carattere. Dovrebbe quindi essere di circa 610 caratteri.

Casi test

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

Il mio primo codice-golf: D

(Non sono sicuro del conteggio, l'ho solo pubblicato online in un conteggio dei personaggi)

L'idea dell'algoritmo è piuttosto negativa, ma è breve. Prova in modo casuale tutte le posizioni per i simboli fino a quando non soddisfano tutti i vincoli. L'ingresso è ad esempio con spazi bianchi

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

Premi dopo quel CTRL + D nella console per terminare la lettura.

Ecco il codice originale che utilizza ancora ',' come delimitatore.

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 byte

Un Python è in arrivo.

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!

Esempi:

$ 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
Benvenuti in PPCG! Questo è il codice golf, quindi ti preghiamo di mostrare alcuni sforzi per risolvere il problema con una quantità minima di codice. Per cominciare, è possibile rimuovere tutti gli spazi bianchi non necessari e utilizzare nomi di variabili, strutture e funzioni a lettera singola. Includi anche la lingua e il conteggio totale dei byte nella parte superiore della risposta.
Martin Ender,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.