ต้นไม้กลายพันธุ์ mtDNA


13

พื้นหลัง:

MtDNA เป็นส่วนหนึ่งของ DNA มนุษย์ที่ส่งผ่านจากแม่ไปสู่เด็กและมันกลายพันธุ์ไม่ค่อย เนื่องจากนี่เป็นเรื่องจริงสำหรับมนุษย์ทุกคนจึงมีความเป็นไปได้ที่จะสร้างต้นไม้ขนาดใหญ่ที่แสดงให้เห็นว่ามนุษย์ทุกคนมีความสัมพันธ์ซึ่งกันและกันผ่านบรรพบุรุษของพวกเขาตลอดทางจนถึง EVE สมมุติฐาน การกลายพันธุ์ทุกครั้งใน MtDNA เมื่อเด็กเกิดมาจะสร้างสาขาย่อยใหม่จากสาขาหลักในต้นไม้

ค้นหาข้อมูลเพิ่มเติมเกี่ยวกับ Mitochondrial DNA (mtDNA) ที่นี่: https://en.wikipedia.org/wiki/Mitochondrial_DNA

วัตถุประสงค์:

โปรแกรมของคุณจะแสดงรายการการนับการกลายพันธุ์ของกิ่งต้นไม้ mtDNA และโปรแกรมของคุณควรแสดงมุมมองแบบต้นไม้

ตัวอย่างอินพุตและเอาต์พุต:

อินพุตเป็นตารางที่คั่นด้วยเซมิโคลอน 3 คอลัมน์พร้อมบรรทัดสำหรับแต่ละสาขา ตัวอย่าง:

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

โปรแกรมของคุณควรแสดงผลมุมมองต้นไม้จากซ้ายไปขวารวมถึงตัวเลขบางส่วนตามอินพุต จากอินพุตตัวอย่างนี่เป็นเอาต์พุตที่ถูกต้อง:

  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]

อินพุต: รายละเอียด

ตารางอินพุตไม่ได้เรียงตามลำดับเฉพาะ หากเราสุ่มเรียงลำดับบรรทัดอินพุตเอาต์พุตใหม่ควรจะยังคงเหมือนเดิม

แต่ละบรรทัดในอินพุตแสดงถึงกิ่งต้นไม้ mtDNA หรือกิ่งต้นไม้สมมุติ ตารางอินพุตอาจมีจำนวนบรรทัดยาวเท่าใดก็ได้

อินพุต: รายละเอียด - คอลัมน์ A (ชื่อสาขา):

คอลัมน์แรกคือชื่อสาขาที่แท้จริง ชื่อแบ่งบรรทัดอินพุตออกเป็น 2 กลุ่มประเภทบรรทัดที่ควรจัดการแตกต่างกัน (อธิบายในภายหลัง) จากกันและกัน:

  • Type 1: ชื่อประกอบด้วย'ส่วนต่อท้ายหรือส่วนต่อท้ายNL
  • ชนิดที่ 2: ชื่อไม่ได้ประกอบด้วยใด ๆหรือคำต่อท้าย'NL

ชื่อมีความยาวสูงสุด 20 อักขระ

อินพุต: รายละเอียด - คอลัมน์ B (ชื่อสาขาหลัก):

คอลัมน์ที่สองประกอบด้วยตัวชี้ไปยังชื่อสาขาหลัก มีหลายบรรทัด (สาขา) สามารถแชร์พาเรนต์เดียวกันได้ มีชื่อสาขาย่อยพาเรนต์ที่แตกต่างกัน 1 รายการในตารางอินพุตที่ชี้ไปยังพาเรนต์ที่ไม่ได้แสดงในบรรทัดอินพุตชื่อสาขาพาเรนต์นั้นเป็นรูทสำหรับต้นไม้ mtEVEในการป้อนข้อมูลตัวอย่างที่บรรทัดที่สามที่ชี้ไปยังราก: หากอินพุตมีมากกว่าหนึ่งรูทหรือลูปไม่สิ้นสุดนั่นคืออินพุตที่ไม่ถูกต้อง

อินพุต: รายละเอียด - คอลัมน์ C (จำนวนการกลายพันธุ์):

คอลัมน์ที่สามคือจำนวนการกลายพันธุ์ทั้งหมดที่สาขาเฉพาะได้นับจากรูท มนุษย์ mtDNA ไม่ได้กลายพันธุ์มากกว่า 100 ครั้งในหนึ่งบรรทัดจากรากมารดาสมมุติ (มนุษย์ / บรรพบุรุษลิงชิมแปนซี EVE) แต่โปรแกรมของคุณควรจะสามารถรับมือกับการกลายพันธุ์ 3 หลักได้ถึง 999

จากอินพุตคุณสามารถคำนวณหมายเลขการกลายพันธุ์ที่ไม่ซ้ำกันได้โดยการแทนที่ # ของการกลายพันธุ์จากการกลายพันธุ์ # ของการกลายพันธุ์

ผลลัพธ์: รายละเอียด

โปรแกรมของคุณควรแสดงข้อความแสดงข้อผิดพลาดที่แตกต่างกัน 1 ใน 3 หากอินพุตไม่ถูกต้องตามคำอธิบายอินพุต

  • ข้อความแสดงข้อผิดพลาด 1 ถ้าอินพุตมีมากกว่าหนึ่งรูท: ERROR: Multiple roots
  • ข้อความแสดงข้อผิดพลาด 2 หากพอยน์เตอร์พอยน์เตอร์อินพุตลูป: ERROR: Endless loop
  • ข้อความแสดงข้อผิดพลาด 3 มีสิ่งใดที่ไม่ถูกต้องเกี่ยวกับอินพุต: ERROR: Invalid input

หากอินพุตไม่มีข้อผิดพลาดโปรแกรมของคุณควรเอาต์พุตทรีตามข้อ จำกัด ต่อไปนี้: แต่ละบรรทัดประกอบด้วย 5 ส่วน A, B, C, D และ E:

  • A: 5 ตัวอักษร, การแปลง # char ที่ถูกจัดเรียง 3 ตัว, อักขระบรรทัดแนวตั้ง: |และ 1 ช่องว่าง
  • B: [จำนวนสูงสุดของการกลายพันธุ์] ตัวละครต้นไม้กว้าง + 1 พื้นที่ว่าง
  • C: 20 ตัวอักษรชื่อสาขาที่จัดชิดซ้าย
  • D: 5 ตัวอักษร 3 ตัวละครจัดชิดขวา # ของการกลายพันธุ์ที่ไม่ซ้ำกันสำหรับสาขาห่อหุ้มระหว่างและ[ ](การกลายพันธุ์ที่ไม่ซ้ำกันจะอธิบายไว้ด้านล่าง)
  • E: 5 ตัวอักษร 3 ตัวละครจัดชิดขวาสูงสุด # ของการกลายพันธุ์รวมสำหรับสาขานี้และเด็กสาขาห่อหุ้มระหว่างและ[]

Branch # ของการกลายพันธุ์ที่ไม่ซ้ำกันคือความแตกต่างใน # ของการกลายพันธุ์ที่สาขาปัจจุบันมีจาก # ของการกลายพันธุ์ที่สาขาแม่ของมันมี บรรทัดแรกคือรูทและควรแสดงด้วย0# ของการกลายพันธุ์และ # ของการกลายพันธุ์ที่ไม่ซ้ำกัน

เอาท์พุท: รายละเอียด - คำสั่งสาย / การเรียงลำดับ

หากสาขาย่อยสองสาขาหรือมากกว่านั้นกำลังแบ่งปันผู้ปกครองคนเดียวกันสาขาจะได้รับคำสั่งจาก # สาขาย่อยสูงสุดของการกลายพันธุ์ทั้งหมดในลำดับถัดลงมา ในตัวอย่างของเราL0a1'4, L0a3และหุ้นแม่:L0a2L0a

ในมุมมองต้นไม้ลำดับจากบนลงล่างคือจำนวนสูงสุดของสาขาย่อยของการกลายพันธุ์ทั้งหมดภายในวงเล็บ: L0a3(53), L0a1'4(55), L0a2(60)

หากสาขาย่อยสองสาขาขึ้นไปมีจำนวนการกลายพันธุ์สูงสุดที่เท่ากันในสาขาย่อยพวกเขาจะถูกจัดเรียงในแนวตั้งและแยกจากพ่อแม่ของพวกเขาจากจุดเดียวกันการเรียงลำดับบรรทัดในสาขาย่อยเหล่านั้นเป็นตัวอักษร

เอาท์พุท: รายละเอียด - ต้นไม้ (ส่วน B)

ต้นไม้ควรจะวาดที่มีตัวอักษร ASCII ต่อไปนี้: , , , , , ,

ตรรกะของต้นไม้คือการกลายพันธุ์ทั้งหมดควรจะแสดง สาขาจากสาขาหลัก: หรือหมายถึง 1 การกลายพันธุ์ การกลายพันธุ์ที่ไม่ซ้ำกันเพิ่มเติมในสาขาเดียวกันนั้นจะถูกแทนด้วย: และพวกเขาจะต้องจัดชิดซ้ายและวางไว้ก่อนสาขาย่อยแรก

กิ่งย่อยย่อยจากพ่อแม่ของพวกเขาตามแนวแกน x และตำแหน่งจะถูกกำหนดโดยจำนวนสูงสุดของการกลายพันธุ์ในหมู่กิ่งย่อยที่ตามมาทั้งหมด

ดังที่ได้กล่าวไว้ก่อนหน้าอินพุตมี 2 บรรทัดอินพุตที่ต่างกัน พิมพ์ 1 ด้วยอักขระ 'ใด ๆ หรือคำต่อท้าย NL ในชื่อสาขาไม่ควรเติมเส้นแนวนอนไปทางขวาสุดของบรรทัด แต่ลงท้ายด้วย a บนสาขาย่อยสุดท้าย ในตัวอย่างจะใช้กับสาขาต่อไปนี้:

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

หวังว่าตัวอย่างอินพุตและเอาต์พุตจะตอบคำถามเพิ่มเติมใด ๆ เกี่ยวกับวิธีการวาดแผนผังพิจารณาว่าเป็นส่วนหนึ่งของความท้าทายในการหาตรรกะ

แรงบันดาลใจ

คุณสามารถทดลองใช้งานจาวาสคริปต์ของฉัน (ไม่ตีกอล์ฟ) เพื่อหาแรงบันดาลใจ: http://artificial.se/DNA/mtDNAmutationTree3.html (ไม่มีการตรวจสอบข้อผิดพลาดและมีการเพิ่มสถิติบางอย่างซึ่งไม่ได้เป็นส่วนหนึ่งของความท้าทายนี้โดยเฉพาะ) .

ต้นไม้รุ่น mtDNA ที่สมบูรณ์ [อ้างอิงจากhttp://www.phylotree.org/ต้นไม้ mtDNA Build 16 (19 ก.พ. 2014)] สามารถพบได้ที่นี่:

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

data-file ที่ใช้สำหรับแผนผังเต็ม:

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

นี่คือความท้าทายรหัส - กอล์ฟ


L0d1ไม่ควรวางไว้ก่อนL0d2ตามกฎการเรียงลำดับ: "... จากมากไปน้อย ... "
guy777

L0a1'4ไม่ใช่ (55) แต่ (39) L0a2ไม่ใช่ (60) แต่ (47) ... คุณช่วยอธิบายได้ไหม?
guy777

L0d1 และ L0d2 มีทั้ง 46 ดังนั้นจึงเรียงตามลำดับตัวอักษร
Plarsen

L0a4 55 และลูกของ L0a1'4 ดังนั้นการกลายพันธุ์สูงสุดสำหรับ L0a1'4 คือ 55
Plarsen

ฉันมีคำถามสองสามข้อ: 1) นี่เป็นโครงการจริงหรือ ฉันมีความประทับใจว่าบางสิ่งเช่นนี้อาจคุ้มค่ากับเงินจริง 2) คุณได้รับผลลัพธ์ตัวอย่างอย่างไร 3) ทำไมส่วน A ถึงมี 8 ตัวอักษรแทนที่จะเป็น 5 4) ทำไมส่วน D ถึงมี 6 ตัวอักษรแทนที่จะเป็น 5 5) ทำไม "L0a1 NL" มี "4" ในตอน D
aditsu ออกจากเพราะ SE นั้นชั่วร้าย

คำตอบ:


6

Python 3, 925 ไบต์

ยายน้อยกว่า 1 KB! อาจเป็นห้องสำหรับเล่นกอล์ฟ ...

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))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.