cây đột biến mtDNA


13

Lý lịch:

MtDNA là một phần của DNA người được truyền từ mẹ sang con và nó hiếm khi bị đột biến. Vì điều này đúng với tất cả mọi người, có thể tạo ra một cái cây khổng lồ để hình dung tất cả con người có liên quan với nhau như thế nào thông qua tổ tiên của mẹ cho đến khi trở thành EVE giả thuyết. Mỗi đột biến trong MtDNA khi một đứa trẻ được sinh ra sẽ tạo ra một nhánh con mới từ nhánh mẹ của nó trên cây.

Tìm hiểu thêm về DNA ty thể (mtDNA) tại đây: https://en.wikipedia.org/wiki/Mitochondrial_DNA

Mục tiêu:

Chương trình của bạn được cung cấp một danh sách đếm đột biến nhánh cây mtDNA và chương trình của bạn sẽ cung cấp chế độ xem dạng cây của nó

Ví dụ đầu vào và đầu ra:

Đầu vào là một bảng được phân tách bằng nửa cột với một dòng cho mỗi nhánh. Thí dụ:

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

Chương trình của bạn sẽ xuất ra chế độ xem cây từ trái sang phải bao gồm một số số dựa trên đầu vào. Dựa trên đầu vào ví dụ, đây là đầu ra hợp lệ:

  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]

Đầu vào: Chi tiết

Bảng đầu vào không được sắp xếp theo thứ tự cụ thể. Nếu chúng ta sắp xếp lại ngẫu nhiên các dòng đầu vào, đầu ra sẽ giữ nguyên.

Mỗi dòng trong đầu vào đại diện cho một nhánh cây mtDNA hoặc một nhánh cây giả định. Bảng đầu vào có thể là bất kỳ số lượng dòng dài.

Đầu vào: Chi tiết - Cột A (tên chi nhánh):

Cột đầu tiên là tên chi nhánh thực tế. Tên chia các dòng đầu vào thành 2 nhóm loại dòng nên được xử lý khác nhau (giải thích sau) với nhau:

  • Loại 1: Tên bao gồm bất kỳ 'hoặc hậu tốNL
  • Loại 2: Tên không bao gồm bất kỳ 'hoặc hậu tố NL.

Tên có thể dài tối đa 20 ký tự.

Đầu vào: Chi tiết - Cột B (tên chi nhánh mẹ):

Cột thứ hai chứa một con trỏ tới tên nhánh cha. Một số dòng (nhánh) có thể chia sẻ cùng cha mẹ. Luôn có chính xác 1 tên nhánh cha riêng biệt trong bảng đầu vào trỏ đến một cha mẹ không được đại diện trong số các dòng đầu vào, tên nhánh cha đó là gốc cho cây. Trong ví dụ đầu vào là dòng thứ ba trỏ đến gốc : mtEVE. Nếu đầu vào có nhiều hơn một gốc hoặc các vòng lặp vô tận thì đó là đầu vào không hợp lệ.

Đầu vào: Chi tiết - Cột C (# đột biến):

Cột thứ ba là tổng số đột biến mà nhánh cụ thể đã đếm từ gốc. MtDNA của con người đã không bị đột biến hơn 100 lần trong một dòng từ gốc mẹ giả định (EVE của tổ tiên / tinh tinh), nhưng chương trình của bạn sẽ có thể xử lý 3 chữ số đột biến, lên tới 999.

Từ đầu vào, bạn có thể tính toán một nhánh # của các đột biến duy nhất bằng cách trừ # đột biến của nó từ # đột biến gốc của nó.

Đầu ra: Chi tiết

Chương trình của bạn sẽ xuất 1 trong 3 thông báo lỗi khác nhau nếu đầu vào không hợp lệ theo mô tả đầu vào.

  • Thông báo lỗi 1, nếu đầu vào có nhiều hơn một gốc: ERROR: Multiple roots
  • Thông báo lỗi 2, nếu các vòng lặp cha mẹ đầu vào vòng lặp: ERROR: Endless loop
  • Thông báo lỗi 3, bất cứ điều gì khác không hợp lệ về đầu vào: ERROR: Invalid input

Nếu đầu vào không có lỗi, chương trình của bạn sẽ xuất cây theo các ràng buộc sau: Mỗi dòng bao gồm 5 phần A, B, C, D và E:

  • A: 5 ký tự, 3 ký tự đột biến # char, một ký tự dọc: |và 1 khoảng trắng
  • B: [max # của đột biến] ký tự cây rộng + 1 khoảng trống
  • C: 20 ký tự, tên nhánh được căn trái
  • D: 5 ký tự, 3 ký tự được căn phải # các đột biến duy nhất cho nhánh được gói gọn giữa []. (Đột biến độc đáo sẽ được giải thích bên dưới).
  • E: 5 ký tự, tối đa 3 ký tự được sắp xếp đúng # tổng số đột biến cho nhánh này và tất cả các nhánh con được gói gọn giữa [].

Một nhánh # của các đột biến duy nhất là sự khác biệt về # các đột biến mà nhánh hiện tại có từ # các đột biến mà nhánh mẹ của nó có. Dòng đầu tiên là gốc và nó phải được đại diện 0cho # đột biến và # đột biến duy nhất.

Đầu ra: Chi tiết - thứ tự dòng / sắp xếp

Nếu hai hoặc nhiều nhánh con đang chia sẻ cùng một cha mẹ, các nhánh được sắp xếp theo số nhánh phụ tối đa # của tổng số đột biến theo thứ tự giảm dần. Trong ví dụ của chúng tôi L0a1'4, L0a3L0a2chia sẻ cha mẹ : L0a.

Trong chế độ xem dạng cây, thứ tự từ trên xuống dưới là, các nhánh con tối đa # tổng số đột biến trong ngoặc đơn: L0a3(53), L0a1'4(55), L0a2(60).

Nếu hai hoặc nhiều nhánh con chia sẻ cùng một số đột biến tối đa trên các nhánh con, chúng được sắp xếp theo chiều dọc và phân nhánh từ cha mẹ của chúng từ cùng một vị trí, thứ tự dòng giữa các nhánh con đó là theo thứ tự bảng chữ cái.

Đầu ra: Chi tiết - cây (phần B)

Cây cần được rút ra với các nhân vật sau đây ascii: , , , , , ,

Logic của cây là tất cả các đột biến nên được biểu diễn. Một nhánh từ nhánh cha: hoặc đại diện cho 1 đột biến. Các đột biến duy nhất khác trên cùng một nhánh được biểu thị bằng: và chúng phải được căn trái và được đặt trước nhánh phụ đầu tiên.

Các nhánh con được phân nhánh từ cha mẹ của chúng dọc theo trục x và vị trí được xác định bởi số đột biến tối đa trong số tất cả các nhánh con tiếp theo.

Như được gợi ý trước khi đầu vào có 2 loại dòng đầu vào khác nhau. Loại 1 có bất kỳ ký tự hoặc hậu tố NL trong tên nhánh, không được điền dòng ngang sang bên phải trên dòng của chúng mà kết thúc bằng một trên nhánh phụ cuối cùng. Trong ví dụ này, nó được áp dụng cho các nhánh sau:

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

Hy vọng rằng ví dụ đầu vào và đầu ra trả lời bất kỳ câu hỏi bổ sung nào về cách cây nên được vẽ, coi đó là một phần của thách thức để tìm ra logic.

Cảm hứng

Bạn được chào đón dùng thử phiên bản javascript (không chơi gôn) của tôi để lấy cảm hứng: http://artificial.se/DNA/mtDNAmutationTree3.html (nó thiếu kiểm tra lỗi, và một số thống kê được thêm vào đó không phải là một phần của thử thách đặc biệt này) .

Một phiên bản cây mtDNA hoàn chỉnh [dựa trên http://www.phylotree.org/ thể tìm thấy mtDNA cây Build 16 (19 tháng 2 năm 2014) tại đây:

http://art mẫu.se / DNA / mtDNAfull.html

Tệp dữ liệu được sử dụng cho toàn cây:

http://art bát.se / DNA / mtDNA_full.txt

Đây là một thách thức mã golf.


L0d1không nên được đặt trước L0d2, theo quy tắc sắp xếp: "... thứ tự giảm dần ..."
chàng777

L0a1'4không phải (55) mà là (39), L0a2không phải (60) mà là (47) ... Bạn có thể làm rõ điều này không?
chàng777

L0d1 và L0d2 đều 46, theo thứ tự bảng chữ cái được áp dụng
Plarsen

L0a4 55 và là con của L0a1'4 nên đột biến tối đa cho L0a1'4 là 55
Plarsen

Tôi có một vài câu hỏi: 1) Đây có phải là một dự án thực sự? Tôi có ấn tượng rằng một cái gì đó như thế này có thể có giá trị tiền thực tế. 2) Làm thế nào bạn có được đầu ra ví dụ? 3) Tại sao phần A có 8 ký tự thay vì 5? 4) Tại sao phần D có 6 ký tự thay vì 5? 5) Tại sao "L0a1 NL" có "4" trong phần D?
aditsu

Câu trả lời:


6

Python 3, 925 byte

Yay, dưới 1 KB! Có lẽ vẫn còn chỗ để chơi gôn ...

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))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.