การตั้งชื่อโซ่คาร์บอนที่ไม่เป็นวงกลม


30

(ฉันไม่ใช่นักเคมี! ฉันอาจจะผิดบางอย่างฉันเขียนสิ่งที่ฉันเรียนรู้ในโรงเรียนมัธยม)

อะตอมของคาร์บอนมีคุณสมบัติพิเศษ: พวกมันสามารถผูกกับอะตอมอื่นอีก 4 อะตอม (ซึ่งไม่ได้เป็นพิเศษนั้น) และพวกมันจะมีความเสถียรแม้ในโซ่ยาวซึ่งเป็นเอกลักษณ์มาก เนื่องจากพวกเขาสามารถถูกล่ามโซ่และรวมกันได้หลายวิธีเราจึงจำเป็นต้องมีการตั้งชื่อแบบแผนการตั้งชื่อพวกเขา

นี่เป็นโมเลกุลที่เล็กที่สุดที่เราสามารถสร้าง:

CH4

มันเรียกว่ามีเธน ประกอบด้วยอะตอมของคาร์บอนเพียงหนึ่งเดียวและไฮโดรเจน 4 อะตอม สิ่งต่อไปคือ:

CH3 - CH3

นี่เรียกว่าอีเธน มันประกอบไปด้วยคาร์บอน 2 อะตอมและไฮโดรเจน 6 อะตอม

2 ต่อไปคือ:

CH3 - CH2 - CH3
CH3 - CH2 - CH2 - CH3

พวกเขาเป็นโพรเพนและบิวเทน ปัญหาเริ่มต้นด้วยโซ่ที่มีอะตอมของคาร์บอน 4 ตัวเนื่องจากสามารถสร้างขึ้นได้ 2 วิธี อันหนึ่งถูกแสดงไว้ด้านบนและอีกอันคือ:

CH3 - CH - CH3
       |
      CH3

เห็นได้ชัดว่าไม่เหมือนกัน จำนวนอะตอมและการผูกต่างกัน แน่นอนว่าการพับการผูกและการหมุนโมเลกุลจะไม่ทำให้มันแตกต่าง! ดังนั้นนี่คือ:

CH3 - CH2 - CH2 - CH3

และนี่:

CH3 - CH2
       |
CH3 - CH2

เหมือนกัน (หากคุณเข้าสู่ทฤษฎีกราฟคุณอาจพูดได้ว่าหากมีมอร์ฟอสฟิซึมระหว่าง 2 โมเลกุลก็เหมือนกัน) จากนี้ไปฉันจะไม่เขียนอะตอมไฮโดรเจนเนื่องจากไม่จำเป็นสำหรับความท้าทายนี้

เมื่อคุณเกลียดเคมีอินทรีย์และคุณมีอะตอมของคาร์บอนแตกต่างกันมากมายคุณตัดสินใจที่จะเขียนโปรแกรมที่ทำเพื่อคุณ คุณไม่มีที่ว่างบนฮาร์ดไดร์ฟของคุณมากเกินไปดังนั้นโปรแกรมต้องมีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้

ความท้าทาย

เขียนโปรแกรมที่เขียนด้วยข้อความหลายบรรทัดเป็นอินพุต (โซ่คาร์บอน) และส่งชื่อของโซ่คาร์บอน ข้อมูลที่ป้อนจะมีช่องว่างเฉพาะอักขระตัวพิมพ์ใหญ่ 'c' และ '|' และ '-' ซึ่งแสดงถึงการเชื่อมโยง ห่วงโซ่อินพุตจะไม่มีรอบ! ตัวอย่าง:

การป้อนข้อมูล:

C-C-C-C-C-C
  |   |
  C   C-C

เอาท์พุท:

4 เอทิล-2-methylhexane

เอาท์พุทใด ๆ ที่เป็นที่ยอมรับตราบเท่าที่มันเป็นมนุษย์อ่านและเป็นหลักเดียวกัน (เพื่อให้คุณสามารถใช้ตัวแยกที่แตกต่างกันเช่นถ้าคุณต้องการ)

แบบแผนการตั้งชื่อ:

(ดู: กฎ IUPAC )

  1. ระบุโซ่คาร์บอนที่ยาวที่สุด ห่วงโซ่นี้เรียกว่าห่วงโซ่ผู้ปกครอง

  2. ระบุองค์ประกอบย่อยทั้งหมด (กลุ่มที่ต่อท้ายจากเชนพาเรนต์)

  3. หมายเลข carbons ของสายโซ่จากปลายที่ให้ substituents ตัวเลขต่ำสุด เมื่อเปรียบเทียบชุดของตัวเลขชุดที่เป็น "ต่ำสุด" คือหมายเลขที่มีตัวเลขต่ำที่สุดในโอกาสที่มีความแตกต่างครั้งแรก หากเชนข้างสองข้างขึ้นไปอยู่ในตำแหน่งที่เท่ากันให้กำหนดจำนวนต่ำสุดให้กับโซ่ที่จะมาก่อนในชื่อ

  4. หากเกิด substituent เดียวกันมากกว่าหนึ่งครั้งจะมีการระบุตำแหน่งของแต่ละจุดที่เกิด substituent นอกจากนี้จำนวนครั้งที่กลุ่ม substituent เกิดขึ้นถูกระบุด้วยคำนำหน้า (di, tri, tetra เป็นต้น)

  5. หากมีองค์ประกอบย่อยที่แตกต่างกันสองรายการขึ้นไปรายการเหล่านั้นจะถูกเรียงลำดับตามตัวอักษรโดยใช้ชื่อฐาน (ละเว้นคำนำหน้า) คำนำหน้าเท่านั้นที่ใช้เมื่อวาง substituents ตามลำดับตัวอักษรคือ iso ใน isopropyl หรือ isobutyl คำนำหน้า sec- และ tert- ไม่ได้ใช้ในการกำหนดลำดับตัวอักษรยกเว้นเมื่อเปรียบเทียบกัน

  6. หากเชนที่มีความยาวเท่ากันกำลังแข่งขันเพื่อเลือกเป็นพาเรนต์โซ่ตัวเลือกจะเป็นชุด:

    • โซ่ที่มีโซ่ข้างจำนวนมากที่สุด
    • ห่วงโซ่ที่มีองค์ประกอบย่อยมีตัวเลขต่ำสุด
    • โซ่ที่มีจำนวนคาร์บอนมากที่สุดในห่วงโซ่ด้านที่เล็กที่สุด
    • โซ่ที่มีโซ่ด้านข้างที่แยกย่อยน้อยที่สุด (กราฟที่มีจำนวนใบน้อยที่สุด

สำหรับเชนพาเรนต์การตั้งชื่อคือ:

Number of carbons   Name
1                  methane
2                  ethane
3                  propane
4                  butane
5                  pentane
6                  hexane
7                  heptane
8                  octane
9                  nonane
10                 decane
11                 undecane
12                 dodecane

โซ่จะไม่ยาวกว่า 12 ดังนั้นจะเพียงพอ สำหรับกลุ่มย่อยมันเหมือนกัน แต่แทนที่จะเป็น 'ane' ในตอนท้ายเรามี 'yl'

คุณสามารถสันนิษฐานได้ว่าCs อยู่ในคอลัมน์คี่และการผูก ( |และ-ตัวอักษร) นั้นยาว 1 ระหว่างอะตอมของคาร์บอน

กรณีทดสอบ:

การป้อนข้อมูล:

C-C-C-C

เอาท์พุท:

บิวเทน

การป้อนข้อมูล:

C-C-C
  |
  C

เอาท์พุท:

2 methylpropane

การป้อนข้อมูล:

C-C-C-C
  |
  C
  |
  C-C

เอาท์พุท:

3 methylhexane

การป้อนข้อมูล:

C-C-C-C-C
  |
  C
  |
  C

เอาท์พุท:

3 methylhexane

การป้อนข้อมูล:

    C
    |
    C
    |
C-C-C-C
  |
  C-C-C
  |
  C-C

เอาท์พุท:

3,4-dimethyl-5-ethylheptane

แก้ไข: ขออภัยสำหรับตัวอย่างที่ผิด ฉันไม่ใช่นักเรียนที่ดี :( ตอนนี้พวกเขาควรได้รับการแก้ไขแล้ว


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Dennis

2
ตามกฎนี้แล้วIf the same substituent occurs more than once, the location of each point on which the substituent occurs is given. In addition, the number of times the substituent group occurs is indicated by a prefix (di, tri, tetra, etc.).ตัวอย่างสุดท้ายไม่ควรเรียกว่า 3,4- di methyl-5-ethylheptane? (เราเพิ่งเริ่มต้นเคมีอินทรีย์ฉันอาจผิด: P)
NieDzejkob

@NieDzejkob ฉันจะเห็นด้วยเนื่องจากมีสองโซ่เมธิล
Jonathan Frech

@NieDzejkob แน่นอนแก้ไข
Peter Lenkefi

คำตอบ:


18

Python 2 , 1876 1871 1870 1859 1846 1830 1826 1843 1900 1932 1813 1847 1833 1635 1613 1596 ไบต์

s=input().split('\n')
W=enumerate
J=len
Y=sorted
l=J(s[0])
s=''.join(s)
S=set
M=max
A=min
p=map
f=lambda k:[(x/l,x%l)for x,V in W(s)if V==k]
g=lambda x,i,h=lambda x,i,j:x[:i]+(x[i]+j,)+x[i+1:]:[(h(q,i,-1),h(q,i,1))for q in x]
v=f('C');e=g(f('-'),1)+g(f('|'),0)
E=[V for V in v if sum(e,()).count(V)==1]
o=lambda v:[E[~E.index(v)]for E in e if v in E]
T=lambda a:lambda b:z((a,b))
Z=lambda a:p(T(a[0]),a[1])
n=lambda R:'mepbphhondudetrueeeco nothotnxptn ddh p t t'[R-1::12].strip()+(R>9)*'ec'
G=lambda K:[H[i]for i,V in W(K)if V==A(K)]
q=lambda x:[`k[0]`for k in H if k[1]==x]
B='-'.join
def z(n,c=[]):k=[x for x in S(o(n[0]))-S(c)];p=[z((j,n[1]),c+k)for j in k];return 1-~-(n[0]==n[1])*(p and A(p)or J(v))
C=[(a,b)for a in E for b in E]
a=p(z,C)
s=[(k,[E for E in v if~-z((k[0],E))+z((k[1],E))==z((k[0],k[1]))])for k in[C[x]for x,V in W(a)if V==M(a)]]
H=[]
R=0
for k,_ in s:R=M(J(_),R);_.sort(key=T(k[0]));a=sum([list(S(o(k))-S(_))for k in _],[]);H+=zip(p(lambda a:Z((a,_)).index(2),a),p(Z,[(O,[x for x in S(v)-S(_)if z((x,O),_)<J(v)])for O in a])),
X=n(R)
U=any(H)
if U:H=G([[h[0]for h in Q]for Q in H if J(Q)==M(p(J,H))]);K=[[J(Q[1])for Q in j]for j in H];H=[H[i]for i,V in W(K)if A(V)==A(sum(K,[]))];K=[J([Q[1]for Q in j if J(S(Q[1]))-J(Q[1])])for j in H];H=[[p[0]+1,n(M(p[1]))+[['isopropyl','butyl-tert','butyl-sec','isobutyl'][J(p[1])+p[1].count(3)-3],'yl'][Y(p[1])==range(1,1+M(p[1]))]]for p in G(K)[0]]
print(U and B([','.join(q(x))+'-'+'dttphhondireeeecoe itnxptnc  rtataaa  aa a '[J(q(x))-2::9].strip()+B(x.split('-')[::-1])for x in Y(list(S(zip(*H)[1])))])+X or[X,'meth']['t'==X])+'ane'

ลองออนไลน์!

เอาล่ะคุณไป ไม่แน่นอนนักกอล์ฟ แต่ใช้งานได้ (ฉันหวังว่า): D

ใช้เวลาประมาณ 10 ชั่วโมง น่าจะเป็นสนามกอล์ฟที่ยาวที่สุดของฉันทั้งในขนาดและเวลาและนั่นคือสิ่งที่ฉันคิดว่าฉันเคยใช้ Java D:

ตรรกะ:

  1. แปลงจากการนำเสนอ ASCII เป็นกราฟแทนด้วยแต่ละอะตอมคาร์บอนเป็นโหนดและแต่ละพันธะเป็นขอบแสดงในรูปแบบ adjacency
  2. ค้นหาใบไม้ทั้งหมด นั่นคือโหนดที่มีพันธะเดียวเท่านั้น ห่วงโซ่ที่ยาวที่สุดรับประกันได้ว่าจะมาจากที่หนึ่งไปยังอีกเหล่านี้
  3. ค้นหาผลิตภัณฑ์ dyadic ของใบ; นั่นคือคู่ของโหนดขอบทั้งหมด จากนั้นใช้ความยาวของโซ่เหล่านี้ทั้งหมด
  4. สำหรับแต่ละเชนให้ค้นหา subchains
  5. ทำสิ่งที่จะเลือกห่วงโซ่ที่เหมาะสม หากมีความสัมพันธ์กันมันก็ไม่สำคัญ ความจริงแล้วสนุก: มันจะเสมอกันเสมอเพราะแต่ละโซ่ถูกนับสองครั้ง
  6. พิมพ์อย่างถูกต้อง

แก้ไข : แก้ไขข้อผิดพลาดที่มันใช้เพื่อทำให้เกิดข้อผิดพลาดหากไม่มีเครือข่ายด้านข้าง

แก้ไข : ขอบคุณ MD XF สำหรับการสังเกตช่องว่างเพิ่มเติมเล็กน้อย (เยื้องสำหรับ for loop)

แก้ไข : ฉันลืมเกี่ยวกับคำนำหน้าเพื่อให้มีเนื้อหาย่อยเดียวกัน

หมายเหตุ : แต่ละบรรทัดต้องมีความกว้างเท่ากันเพื่อให้ทำงานได้ นั่นคือต้องการช่องว่างต่อท้าย

ความจริงแล้วสนุก: ไฮโดรคาร์บอนไซโคลส่วนใหญ่จะถูกพิจารณาเป็น "มีเทน"

สนุกจริง: ถ้าคุณทำC-C-...-C-Cกับ 13 Cs ก็จะให้ethaneแล้วthane14, ropane15 ฯลฯ

-79 ไบต์ขอบคุณ Jonathan Frech
-119
ไบต์ขอบคุณNieDzejkob -17 ไบต์ขอบคุณ ovs

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