Rosetta Stone Challenge: Генографічне картографування


11

Мета Challenge Rosetta Stone - написати рішення на якомога більшій кількості мов. Покажіть багатомовність програмування!

Змагання

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

Що таке "генографічне відображення?"

Картографування генів - це процес локалізації відносного положення генів на хромосомах. Це робиться шляхом вимірювання частоти схрещування пар генів, рівних відсоткам потомства, при якому ця пара не успадковується разом. Відстань вимірюється в одиницях карт, при цьому одна одиниця карт дорівнює одному відсотку перетину. Наприклад, якщо гени 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

Це також не є абсолютно жорсткою вимогою. Наприклад, ви можете використовувати щось, крім періодів, як коми або пробіли.

Об'єктивний критерій виграшу

Що стосується об'єктивного критерію виграшу, то ось він: Кожна мова - це окремий конкурс щодо того, хто може написати найкоротший запис, але загальним переможцем буде та людина, яка виграє більшість із цих підконкурсів. Це означає, що людина, яка відповідає на багатьох незвичайних мовах, може отримати перевагу. Код-гольф - це здебільшого краватка, коли в мові існує більше одного рішення: особа, яка має найкоротшу програму, отримує заслуги за цю мову.

Правила, обмеження та примітки

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


Поточна таблиця лідерів

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

  • AutoHotkey (632) - Аві
  • dj (579) - рубік

Поточні рейтинги користувачів

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

Чи слід включати код для читання введення? Або ми просто вважаємо, що вхід передається як перший аргумент функції?
Взуття

@ Джеффрі Я гадаю, що будь-який з них добре.
PhiNotPi

.. таблиця лідерів? :-)
Avi

1
Які межі введення? Не так вже й багато n, але в першу чергу межі переходу через частоту (відстань). Чи можемо ми припустити, що завжди буде, скажімо, менше, ніж 1000?
rubik

@PhiNotPi: чи можете ви надати ще пару тестових випадків? Я майже закінчив свою і хотів би перевірити її більше.
rubik

Відповіді:


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

Пітон 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.