Rosetta Stone Challenge: картирование генов


11

Целью Rosetta Stone Challenge является написание решений на максимально возможном количестве языков. Покажите свое программирование многоязычия!

Соревнование

Ваша задача состоит в том, чтобы реализовать программу, которая отобразит некоторые гены с использованием перекрестных частот на максимально возможном количестве языков программирования . Вам разрешается использовать любую стандартную библиотечную функцию, имеющуюся в вашем языке, поскольку это в основном демонстрация языка.

Что такое "картирование генов"?

Картирование генов - это процесс определения местоположения генов на хромосомах. Это делается путем измерения частоты скрещивания пар генов, равной проценту потомства, в котором эта пара не наследуется вместе. Расстояние измеряется в единицах карты, причем одна единица карты равна одному проценту пересечения. Например, если гены 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 - это, в основном, тай-брейк, когда на языке существует более одного решения: человек с самой короткой программой получает кредит на этот язык.

Правила, ограничения и примечания

Ваша программа может быть написана на любом языке, существовавшем до 20 декабря 2013 года. Мне также придется полагаться на сообщество, чтобы проверить некоторые ответы, написанные на некоторых из более необычных / эзотерических языков, так как я вряд ли смогу протестировать их.


Текущий список лидеров

Этот раздел будет периодически обновляться, чтобы показать количество языков и лидирующих в каждом.

  • AutoHotkey (632) - Ави
  • DJ (579) - Рубик

Рейтинг текущих пользователей

  1. Ави (1): AutoHotkey (632)
  2. Рубик (1): DJ (579)

Должны ли мы включить код для чтения ввода? Или мы должны просто предположить, что ввод передается в качестве первого аргумента функции?
Чистка

@ Джефффри Полагаю, все в порядке.
PhiNotPi

.. лидеров? :-)
Ави

1
Каковы входные границы? Не так много n, но прежде всего границы для пересечения частоты (расстояния). Можем ли мы предположить, что это будет, скажем, меньше 1000?
Рубик

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

Код можно укоротить, переименовав все переменные в 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

дг - 717 579 байт

Питон один входит.

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! Это кодовый гольф, поэтому, пожалуйста, приложите некоторые усилия, чтобы решить эту проблему в минимальном количестве кода. Для начала вы можете удалить все ненужные пробелы и использовать однобуквенные имена переменных, структур и функций. Пожалуйста, включите язык и общее количество байтов в верхней части вашего ответа.
Мартин Эндер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.