Rosetta Stone Challenge: Gene Mapping

11

Celem Stone Rosetta Challenge jest pisanie rozwiązań w jak największej liczbie języków. Pochwal się swoją wielojęzycznością programistyczną!

Wyzwanie

Twoim wyzwaniem jest wdrożenie programu, który zmapuje niektóre geny za pomocą częstotliwości rozgraniczających, w jak największej liczbie języków programowania . Możesz używać dowolnej standardowej funkcji bibliotecznej, którą posiada Twój język, ponieważ jest to głównie prezentacja języka.

Co to jest „mapowanie genów”?

Mapowanie genów to proces lokalizowania względnej pozycji genów na chromosomach. Odbywa się to poprzez pomiar częstotliwości krzyżowania par genów, równej procentowi potomstwa, w którym ta para nie jest dziedziczona razem. Odległość jest mierzona w jednostkach mapy z jedną jednostką mapy równą jednemu procentowi przekroczenia. Na przykład, jeśli geny C i D mają częstotliwość krzyżowania wynoszącą 11%, wówczas gen C znajduje się w odległości 11 jednostek mapy od genu D.

Mapowanie genów przeprowadza się przy użyciu wielu par genów w celu ustalenia ich względnej kolejności. Na przykład dane (A,B,12) (D,B,7) (A,D,5) (D,H,2) (H,B,9)tworzą następującą mapę:

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

Być może zauważyłeś, że B......D.H..Ajest to również ważna mapa. To prawda, ponieważ nie można odróżnić lustrzanych przeciwieństw. Twój program może wybrać, który z nich wydrukować. Chociaż dane wejściowe mogą nie obejmować każdej możliwej pary, zawsze będzie wystarczająca ilość informacji, aby zrekonstruować całą mapę (więc nigdy nie będzie więcej niż 2 prawidłowe dane wyjściowe). Ponadto liczby zawsze będą się sprawdzać (w przeciwieństwie do faktycznej biologii), co oznacza, że ​​nie będziesz mieć takich rzeczy (A,B,3) (B,C,4) (A,C,13).

Wejście

Wprowadzanie rozpocznie się od liczby, npo której nastąpi lista genów (wielkie litery). Będą wtedy ntrojaczki danych. Każdy zestaw będzie się składał z pary genów i ich krzyżowania na częstotliwości (odległości).

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

Dane wejściowe nie są sztywno zdefiniowane, ponieważ różne języki mogą mieć ograniczenia co do wykonalności. Na przykład możesz zmienić separatory na coś innego niż przecinki i znaki nowej linii. Formatowanie danych wejściowych zależy w dużej mierze od Ciebie.

Wynik

Wyjście będzie interpretacją mapy genów. Będzie się składał z genów (wielkich liter) rozmieszczonych w odstępach tak, aby odległości były dokładnie przedstawione. Oto wyniki dla powyższych przykładów.

P..HI  *or*  IH..P

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

To również nie jest całkowicie sztywny wymóg. Na przykład możesz użyć czegoś innego niż kropki, takiego jak przecinki lub spacje.

Kryterium zwycięskiego celu

Jeśli chodzi o obiektywne kryterium wygranej, oto on: Każdy język to osobny konkurs na to, kto może napisać najkrótszą pracę, ale ogólnym zwycięzcą byłaby osoba, która wygra najwięcej z tych pod-konkursów. Oznacza to, że osoba, która odpowiada w wielu nietypowych językach, może zyskać przewagę. Code-golf jest przeważnie rozstrzygający, gdy istnieje więcej niż jedno rozwiązanie w języku: osoba z najkrótszym programem otrzymuje kredyt za ten język.

Reguły, ograniczenia i uwagi

Twój program może być napisany w dowolnym języku, który istniał przed 20 grudnia 2013 r. Będę też musiał polegać na społeczności, aby zweryfikować niektóre odpowiedzi napisane w niektórych bardziej rzadkich / ezoterycznych językach, ponieważ jest mało prawdopodobne, że będę w stanie przetestować im.


Aktualny ranking

Ta sekcja będzie okresowo aktualizowana, aby pokazać liczbę języków i kto prowadzi w każdym z nich.

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

Aktualne rankingi użytkowników

  1. Avi (1): AutoHotkey (632)
  2. rubik (1): dj (579)
PhiNotPi
źródło
Czy powinniśmy dołączyć kod do odczytu danych wejściowych? Czy też powinniśmy założyć, że dane wejściowe są przekazywane jako pierwszy argument funkcji?
But
@Jefffrey Chyba jedno z nich jest w porządku.
PhiNotPi
.. tabela wyników? :-)
Avi
1
Jakie są granice wejściowe? Nie tyle n, ale przede wszystkim granice przekroczenia częstotliwości (odległości). Czy możemy założyć, że zawsze będzie to, powiedzmy, mniej niż 1000?
rubik
@PhiNotPi: czy możesz podać jeszcze kilka przypadków testowych? Prawie skończyłem mój i chciałbym go jeszcze przetestować.
rubik

Odpowiedzi:

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

Kod można skrócić, zmieniając nazwę wszystkich zmiennych na 1 znak. Powinno to wynosić około 610 znaków.

Przypadki testowe

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
źródło
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(".")

Mój pierwszy golf-golf: D

(Nie jestem pewien co do liczenia, po prostu umieszczam go online w liczbie znaków)

Idea algorytmu jest dość zła, ale jest krótka. Wypróbuj losowo wszystkie pozycje symboli, dopóki nie spełnią wszystkich ograniczeń. Na przykład wejście zawiera spacje

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

Naciśnij po tym CTRL + D w konsoli, aby zakończyć czytanie.

Oto oryginalny kod, który nadal używa „,” jako separatora.

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
źródło
0

dg - 717 579 bajtów

Nadchodzi 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!

Przykłady:

$ 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
źródło
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
źródło
3
Witamy w PPCG! To jest kod golfowy, więc proszę wykazać się wysiłkiem, aby rozwiązać problem przy minimalnej ilości kodu. Na początek możesz usunąć wszystkie niepotrzebne białe znaki i użyć jednoliterowych nazw zmiennych, struktur i funkcji. Na górze odpowiedzi podaj także język i całkowitą liczbę bajtów.
Martin Ender,