mtDNA mutasyon ağacı


13

Arka fon:

MtDNA, bir insandan bir çocuğa geçen insan DNA'sının bir parçasıdır ve nadiren mutasyon geçirir. Bu, tüm insanlar için geçerli olduğundan, varsayımsal EVE'ye kadar tüm insanların anne soyları aracılığıyla birbirleriyle nasıl ilişkilendiğini görselleştiren dev bir ağaç oluşturmak mümkündür. Bir çocuk doğduğunda MtDNA'daki her mutasyon, ağaçtaki ana dalından yeni bir alt dal oluşturur.

Mitokondriyal DNA (mtDNA) hakkında daha fazla bilgiyi burada bulabilirsiniz: https://en.wikipedia.org/wiki/Mitochondrial_DNA

Amaç:

Programınıza mtDNA ağaç dalları mutasyon sayısının bir listesi sunulur ve programınız bunun bir ağaç görünümünü sunmalıdır

Örnek giriş ve çıkış:

Giriş, her dal için bir çizgi içeren 3 sütunlu yarı kolondan ayrılmış bir tablodur. Misal:

L0a'b'f'k;L0;14
L0a'b'f;L0a'b'f'k;23
L0;mtEVE;10
L0a'b;L0a'b'f;30
L0a;L0a'b;38
L0a1'4;L0a;39
L0a1;L0a1'4;40
L0a1a;L0a1;42
L0a1a NL;L0a1a;43
L0a1a1;L0a1a NL;44
L0a1a2;L0a1a NL;45
L0a1a3;L0a1a NL;44
L0a1 NL;L0a1;41
L0a1b;L0a1 NL;44
L0a1b NL;L0a1b;45
L0a1b1;L0a1b NL;46
L0a1b1a;L0a1b1;47
L0a1b1a1;L0a1b1a;48
L0a1b2;L0a1b NL;48
L0a1b2a;L0a1b2;50
L0a1c;L0a1 NL;45
L0a1d;L0a1 NL;44
L0a4;L0a1'4;55
L0a2;L0a;47
L0a2a;L0a2;49
L0a2a1;L0a2a;50
L0a2a1a;L0a2a1;51
L0a2a1a1;L0a2a1a;53
L0a2a1a2;L0a2a1a;53
L0a2a2;L0a2a;53
L0a2a2a;L0a2a2;54
L0a2b;L0a2;57
L0a2b1;L0a2b;58
L0a2c;L0a2;60
L0a2d;L0a2;49
L0a3;L0a;53
L0b;L0a'b;48
L0f;L0a'b'f;37
L0f1;L0f;61
L0f2;L0f;41
L0f2a;L0f2;46
L0f2a1;L0f2a;59
L0f2b;L0f2;63
L0k;L0a'b'f'k;39
L0k1;L0k;48
L0k2;L0k;54
L0d;L0;21
L0d1'2;L0d;25
L0d1;L0d1'2;30
L0d1 NL;L0d1;31
L0d1a;L0d1 NL;38
L0d1a1;L0d1a;41
L0d1c;L0d1 NL;39
L0d1c1;L0d1c;45
L0d1c1a;L0d1c1;46
L0d1c1b;L0d1c1;46
L0d1b;L0d1 NL;36
L0d1b1;L0d1b;40
L0d2;L0d1'2;31
L0d2a'b;L0d2;32
L0d2a;L0d2a'b;42
L0d2a1;L0d2a;43
L0d2b;L0d2a'b;46
L0d2c;L0d2;45
L0d3;L0d;39

Programınız, girdiye dayalı bazı sayılar içeren soldan sağa bir ağaç görünümü çıkarmalıdır. Örnek girdiye dayanarak, bu geçerli çıktıdır:

  0│ ┐                                                               mtEVE               [  0][ 63]
 10│ └♦♦♦♦♦♦♦♦♦┬────────────────┬─────────────────────────────────── L0                  [ 10][ 63]
 21│           │                └♦♦♦♦♦♦♦♦♦♦┬──────┬───────────────── L0d                 [ 11][ 46]
 39│           │                           │      └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0d3                [ 18][ 39]
 25│           │                           └♦♦♦┐                     L0d1'2              [  4][ 46]
 30│           │                               ├♦♦♦♦┬─────────────── L0d1                [  5][ 46]
 31│           │                               │    └┬────┬┐         L0d1 NL             [  1][ 46]
 36│           │                               │     │    │└♦♦♦♦┬─── L0d1b               [  5][ 40]
 40│           │                               │     │    │     └♦♦♦ L0d1b1              [  4][ 40]
 38│           │                               │     │    └♦♦♦♦♦♦┬── L0d1a               [  7][ 41]
 41│           │                               │     │           └♦♦ L0d1a1              [  3][ 41]
 39│           │                               │     └♦♦♦♦♦♦♦┬────── L0d1c               [  8][ 46]
 45│           │                               │             └♦♦♦♦♦┬ L0d1c1              [  6][ 46]
 46│           │                               │                   ├ L0d1c1a             [  1][ 46]
 46│           │                               │                   └ L0d1c1b             [  1][ 46]
 31│           │                               └♦♦♦♦♦┬┬───────────── L0d2                [  6][ 46]
 45│           │                                     │└♦♦♦♦♦♦♦♦♦♦♦♦♦ L0d2c               [ 14][ 45]
 32│           │                                     └┬──┐           L0d2a'b             [  1][ 46]
 42│           │                                      │  └♦♦♦♦♦♦♦♦♦┬ L0d2a               [ 10][ 43]
 43│           │                                      │            └ L0d2a1              [  1][ 43]
 46│           │                                      └♦♦♦♦♦♦♦♦♦♦♦♦♦ L0d2b               [ 14][ 46]
 14│           └♦♦♦┬────────┐                                        L0a'b'f'k           [  4][ 63]
 39│               │        └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦┬─────┬──────── L0k                 [ 25][ 54]
 48│               │                                 │     └♦♦♦♦♦♦♦♦ L0k1                [  9][ 48]
 54│               │                                 └♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0k2                [ 15][ 54]
 23│               └♦♦♦♦♦♦♦♦┬──┐                                     L0a'b'f             [  9][ 63]
 30│                        │  └♦♦♦♦♦♦┬───────────┐                  L0a'b               [  7][ 60]
 48│                        │         │           └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0b                 [ 18][ 48]
 38│                        │         └♦♦♦♦♦♦♦┬────┬─┬────────────── L0a                 [  8][ 60]
 53│                        │                 │    │ └♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0a3                [ 15][ 53]
 39│                        │                 │    └┬────┐           L0a1'4              [  1][ 55]
 40│                        │                 │     │    └┬────┬──── L0a1                [  1][ 50]
 42│                        │                 │     │     │    └♦┬── L0a1a               [  2][ 45]
 43│                        │                 │     │     │      └┬┐ L0a1a NL            [  1][ 45]
 44│                        │                 │     │     │       │├ L0a1a1              [  1][ 44]
 44│                        │                 │     │     │       │└ L0a1a3              [  1][ 44]
 45│                        │                 │     │     │       └♦ L0a1a2              [  2][ 45]
 41│                        │                 │     │     └┬────┬┐   L0a1 NL             [  1][ 50]
 44│                        │                 │     │      │    │└♦♦ L0a1d               [  3][ 44]
 45│                        │                 │     │      │    └♦♦♦ L0a1c               [  4][ 45]
 44│                        │                 │     │      └♦♦┬───── L0a1b               [  3][ 50]
 45│                        │                 │     │         └┬─┐   L0a1b NL            [  1][ 50]
 46│                        │                 │     │          │ └┬─ L0a1b1              [  1][ 48]
 47│                        │                 │     │          │  └┬ L0a1b1a             [  1][ 48]
 48│                        │                 │     │          │   └ L0a1b1a1            [  1][ 48]
 48│                        │                 │     │          └♦♦┬─ L0a1b2              [  3][ 50]
 50│                        │                 │     │             └♦ L0a1b2a             [  2][ 50]
 55│                        │                 │     └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0a4                [ 16][ 55]
 47│                        │                 └♦♦♦♦♦♦♦♦┬─┬───┬────┬─ L0a2                [  9][ 60]
 49│                        │                          │ │   │    └♦ L0a2d               [  2][ 49]
 49│                        │                          │ │   └♦┬┬─── L0a2a               [  2][ 54]
 50│                        │                          │ │     │└┬── L0a2a1              [  1][ 53]
 51│                        │                          │ │     │ └┬─ L0a2a1a             [  1][ 53]
 53│                        │                          │ │     │  ├♦ L0a2a1a1            [  2][ 53]
 53│                        │                          │ │     │  └♦ L0a2a1a2            [  2][ 53]
 53│                        │                          │ │     └♦♦♦┬ L0a2a2              [  4][ 54]
 54│                        │                          │ │         └ L0a2a2a             [  1][ 54]
 57│                        │                          │ └♦♦♦♦♦♦♦♦♦┬ L0a2b               [ 10][ 58]
 58│                        │                          │           └ L0a2b1              [  1][ 58]
 60│                        │                          └♦♦♦♦♦♦♦♦♦♦♦♦ L0a2c               [ 13][ 60]
 37│                        └♦♦♦♦♦♦♦♦♦♦♦♦♦┬─┬─────────────────────── L0f                 [ 14][ 63]
 61│                                      │ └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0f1                [ 24][ 61]
 41│                                      └♦♦♦┬───┬───────────────── L0f2                [  4][ 63]
 46│                                          │   └♦♦♦♦┬──────────── L0f2a               [  5][ 59]
 59│                                          │        └♦♦♦♦♦♦♦♦♦♦♦♦ L0f2a1              [ 13][ 59]
 63│                                          └♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ L0f2b               [ 22][ 63]

Giriş: Ayrıntılar

Giriş tabloda gösterilmiştir olmayan herhangi bir sırayla dizildi. Giriş satırlarını rastgele yeniden sıralarsak, çıktı aynı kalmalıdır.

Girdideki her satır bir mtDNA ağaç dalını veya varsayımsal bir ağaç dalını temsil eder. Giriş tablosu herhangi bir sayıda satır uzunluğunda olabilir.

Girdi: Ayrıntılar - A Sütunu (dal adı):

İlk sütun, gerçek dal adıdır. Ad, giriş satırlarını birbirinden farklı (daha sonra açıklanacak) ele alınması gereken 2 satır türü grubuna böler:

  • Tip 1: İsim herhangi bir 'veya son ekden oluşurNL
  • Tip 2: İsim herhangi bir 'veya sonek içermez NL.

Ad en fazla 20 karakter uzunluğunda olabilir.

Girdi: Ayrıntılar - B Sütunu (üst dal adı):

İkinci sütun üst dal adına bir işaretçi içerir. Birkaç satır (dal) aynı üst öğeyi paylaşabilir. Giriş tablosunda her zaman tam olarak 1 ayrı üst şube adı vardır ve bu girdi satırları arasında temsil edilmeyen bir ana öğeye işaret eder, bu ana şube adı ağacın köküdür. Üçüncü satır köküne işaret örnek girişinde: mtEVE. Girişin birden fazla kökü veya sonsuz döngüsü varsa, geçersiz bir girdidir.

Girdi: Ayrıntılar - Sütun C (mutasyon sayısı):

Üçüncü sütun, belirli bir dalın kökten saydığı toplam mutasyon sayısıdır. İnsan mtDNA'sı varsayımsal maternal kökten (İnsan / şempanze atası EVE) tek bir satırda 100 defadan fazla mutasyona uğramamıştır, ancak programınız 999'a kadar 3 basamaklı mutasyonları işleyebilmelidir.

Girişten, benzersiz mutasyonların dalını #, mutasyonların # üst mutasyonlarından çıkararak hesaplayabilirsiniz.

Çıktı: Ayrıntılar

Giriş, giriş açıklamasına göre geçersizse, programınız 3 farklı hata mesajından 1'ini çıkarmalıdır.

  • Girişte birden fazla kök varsa hata mesajı 1: ERROR: Multiple roots
  • Giriş üst işaretçileri döngüye girerse, hata iletisi 2: ERROR: Endless loop
  • Hata mesajı 3, giriş hakkında geçersiz olan herhangi bir şey: ERROR: Invalid input

Giriş hata içermiyorsa, programınız ağacı aşağıdaki sınırlamalara göre çıkarmalıdır: Her satır 5 bölüm A, B, C, D ve E'den oluşur:

  • A: 5 karakter, 3 karakter sağa hizalanmış mutasyon sayısı, dikey çizgi karakteri: |ve 1 boşluk
  • B: [maksimum mutasyon sayısı] karakter genişliğinde ağaç + 1 boşluk
  • C: 20 karakter, sola hizalanmış dal adı
  • D: 5 karakter, 3 karakter sağa hizalanmış [ve arasında kapsüllenmiş dal için benzersiz mutasyon sayısı ]. (Eşsiz mutasyonlar aşağıda açıklanacaktır).
  • E: 5 karakter, toplam bu şube için mutasyonlar arasında kapsüllü tüm alt-dallar 3 karakter sağa hizalanmış maksimum # [ve ].

Benzersiz mutasyonların bir dalı, mevcut dalın ana dalının sahip olduğu mutasyon # sayısından farklılığıdır. İlk satır 0köktür ve # mutasyon ve benzersiz mutasyon # sayısı ile temsil edilmelidir .

Çıktı: Ayrıntılar - satır sırası / sıralama

İki veya daha fazla alt dal aynı üst öğeyi paylaşıyorsa, dallar alt dallar tarafından en fazla toplam mutasyon sayısı azalan sırada sıralanır. Örneğimizde L0a1'4, L0a3ve L0a2hisse veli: L0a.

Ağaç görünümünde yukarıdan aşağıya sıra, alt dallarda parantez içindeki toplam mutasyonların maksimum sayısı: L0a3(53), L0a1'4(55), L0a2(60).

İki veya daha fazla alt dal, alt dallarda aynı maksimum mutasyon sayısını paylaşıyorsa, bunlar aynı noktadan ebeveynlerinden dikey olarak hizalanır ve dallanır, bu alt dallar arasındaki satır sırası alfabetiktir.

Çıktı: Ayrıntılar - ağaç (bölüm B)

Ağaç şu ASCII karakterlerle çizilmelidir: , , , , , ,

Ağacın mantığı, tüm mutasyonların temsil edilmesi gerektiğidir. Bir ana daldan bir dal: veya 1 mutasyonu temsil eder. Aynı daldaki ek benzersiz mutasyonlar aşağıdakilerle temsil edilir: bunlar sola hizalanmalı ve ilk alt daldan önce yerleştirilmelidir.

Alt dallar ebeveynlerinden x ekseni boyunca dallanır ve konum sonraki tüm alt dallar arasındaki maksimum mutasyon sayısı ile belirlenir.

Daha önce belirtildiği gibi, girişin 2 farklı giriş hattı türü vardır. Herhangi bir 'karakteri veya şube adında NL soneki olan 1 yazın, satırlarında en sağdaki yatay çizgiyi doldurmamalı, ancak son alt dalda a ile bitmelidir . Örnekte aşağıdaki dallara uygulanır:

L0a'b'f'k;L0;14
L0a'b'f;L0a'b'f'k;23
L0a'b;L0a'b'f;30
L0a1'4;L0a;39
L0a1a NL;L0a1a;43
L0a1 NL;L0a1;41
L0a1b NL;L0a1b;45
L0d1'2;L0d;25
L0d1 NL;L0d1;31
L0d2a'b;L0d2;32

Umarım örnek girdi ve çıktı, ağacın nasıl çizilmesi gerektiği hakkında ek soruları yanıtlar, mantığı bulmak için zorluğun bir parçası olduğunu düşünün.

İlham

İlham almak için (golf edilmemiş) javascript sürümümü deneyebilirsiniz: http://artificial.se/DNA/mtDNAmutationTree3.html (hata kontrolünden yoksun ve bu özel zorluğun bir parçası olmayan bazı istatistikler eklendi) .

Tam bir mtDNA ağacı sürümü [ http://www.phylotree.org/ mtDNA tree Build 16 (19 Şubat 2014) tabanlı ] burada bulunabilir:

http://artificial.se/DNA/mtDNAfull.html

Tüm ağaç için kullanılan veri dosyası:

http://artificial.se/DNA/mtDNA_full.txt

Bu bir kod-golf mücadelesi.


L0d1L0d2Sıralama kuralına göre daha önce yerleştirilmemelidir : "... azalan düzen ..."
guy777

L0a1'4(55) değil (39), L0a2(60) değil (47) ... Bunu açıklığa kavuşturabilir misiniz?
guy777

L0d1 ve L0d2'nin her ikisi de 46'dır, bu nedenle alfabetik sıralama uygulanır
Plarsen

L0a4 55 ve L0a1'4'ün bir çocuğu, bu yüzden L0a1'4 için maksimum mutasyon 55
Plarsen

Birkaç sorum var: 1) Bu gerçek bir proje mi? Böyle bir şeyin gerçek paraya değebileceği izlenimini edindim. 2) Örnek çıktıyı nasıl aldınız? 3) A kısmı neden 5 yerine 8 karakter içeriyor? 4) D bölümünün neden 5 yerine 6 karakteri var? 5) D bölümünde "L0a1 NL" neden "4" var?
aditsu bıraktı çünkü SE EVIL

Yanıtlar:


6

Python 3, 925 bayt

Yay, 1 KB'ın altında! Muhtemelen hala golf için yer ...

import sys
class L:
 def __init__(x,**k):x.__dict__.update(k)
m={}
def e(x):print('ERROR: '+x);exit()
try:
 for x in sys.stdin:a,b,c=x.split(';');m[a]=L(s=a,p=b,m=int(c),l=0)
except:e('Invalid input')
a=set()
def k(x):
 if x.l<0:e('Endless loop')
 if x.l<1:y=m.get(x.p);x.l=-1;k(y)if y else a.add(x.p);x.l=1
for x in m:k(m[x])
r=L(s=a.pop(),p=0,m=0)
if a:e('Multiple roots')
m[r.s]=r
c={}
def u(x):
 c[x.s]=[m[y]for y in m if m[y].p==x.s];x.x=x.m
 for y in c[x.s]:u(y);x.x=max(x.x,y.x)
u(r)
o=[]
def f(p,x,o=o):
 d=x.m-p.m;j=p.m+r.x-x.x;s=x.s;x.i=len(o);l=sorted(c[s],key=lambda t:(t.x,t.s));q=' '*j+'└'+'♦'*(d-1);z='─'
 if"'"in s or s[-2:]=='NL'or x==r:q+=z*(x.x-l[0].x);z=' '
 o+=list("%3d│ "%x.m+q+z*(r.x-len(q))+' %-20s[%3d][%3d]'%(s,d,x.x)),;j+=5;o[p.i][j]='┐┬'[o[p.i][j]in'─┬']
 for i in range(p.i+1,x.i):o[i][j]='├│'[o[i][j]in' │']
 for y in l:f(x,y)
f(r,r)
print('\n'.join(''.join(x)for x in o))
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.