Memberi nama rantai karbon non-siklik

30

(Saya bukan ahli kimia! Saya mungkin salah dalam beberapa hal, saya menulis apa yang saya pelajari di sekolah menengah)

Atom karbon memiliki atribut khusus: Mereka dapat berikatan dengan 4 atom lainnya (yang tidak istimewa) dan mereka tetap stabil bahkan dalam rantai panjang, yang sangat unik. Karena mereka dapat dirantai dan digabungkan dalam banyak cara yang berbeda, kita perlu semacam konvensi penamaan untuk memberi nama mereka.

Ini adalah molekul terkecil yang bisa kita buat:

CH4

Itu disebut metana. Ini terdiri dari hanya satu karbon dan 4 atom hidrogen. Yang berikutnya adalah:

CH3 - CH3

Ini disebut etana. Itu terdiri dari 2 karbon dan 6 atom hidrogen.

2 selanjutnya adalah:

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

Mereka adalah propana dan butana. Permasalahan dimulai dengan rantai dengan 4 atom karbon, karena dapat dibangun dengan 2 cara berbeda. Satu ditunjukkan di atas dan yang lainnya adalah:

CH3 - CH - CH3
       |
      CH3

Ini jelas tidak sama dengan yang lain. Jumlah atom dan ikatannya berbeda. Tentu saja hanya melipat binding dan memutar molekul tidak akan membuatnya berbeda! Jadi ini:

CH3 - CH2 - CH2 - CH3

Dan ini:

CH3 - CH2
       |
CH3 - CH2

Apakah sama (Jika Anda tertarik pada teori grafik, Anda dapat mengatakan bahwa jika ada isomorfisme antara 2 molekul; keduanya sama). Mulai sekarang saya tidak akan menulis atom hidrogen karena mereka tidak penting untuk tantangan ini.

Ketika Anda membenci kimia organik dan Anda memiliki banyak atom karbon yang berbeda, Anda memutuskan untuk menulis sebuah program yang melakukan ini untuk Anda. Anda tidak memiliki terlalu banyak ruang pada hard drive Anda, jadi programnya harus sekecil mungkin.

Tantangan

Tulis program yang menggunakan teks multi-baris sebagai input (rantai karbon) dan output nama rantai karbon. Input hanya akan berisi spasi, huruf besar 'c' dan '|' dan '-' yang mewakili ikatan. Rantai input tidak akan pernah mengandung siklus! Contoh:

Memasukkan:

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

Keluaran:

4-etil-2-metilheksana

Output apa pun dapat diterima asalkan dapat dibaca oleh manusia dan pada dasarnya sama (sehingga Anda dapat menggunakan pemisah yang berbeda misalnya jika Anda mau).

Konvensi penamaan:

(Lihat: aturan IUPAC )

  1. Identifikasi rantai karbon terpanjang. Rantai ini disebut rantai induk.

  2. Identifikasi semua substituen (grup yang ditambahkan dari rantai induk).

  3. Beri nomor karbon pada rantai induk dari ujung yang memberikan substituen angka terendah. Ketika membandingkan serangkaian angka, seri yang merupakan "terendah" adalah yang berisi angka terendah pada kesempatan perbedaan pertama. Jika dua atau lebih rantai samping berada pada posisi yang setara, tetapkan angka terendah ke rantai yang akan didahulukan dalam nama.

  4. Jika substituen yang sama terjadi lebih dari sekali, lokasi setiap titik di mana substituen terjadi diberikan. Selain itu, berapa kali kelompok substituen terjadi ditunjukkan oleh awalan (di, tri, tetra, dll.).

  5. Jika ada dua atau lebih substituen yang berbeda, mereka terdaftar dalam urutan abjad menggunakan nama dasar (abaikan awalan). Satu-satunya awalan yang digunakan saat meletakkan substituen dalam urutan abjad adalah iso seperti pada isopropil atau isobutyl. Awalan kedua dan ters- tidak digunakan dalam menentukan urutan alfabet kecuali jika dibandingkan satu sama lain.

  6. Jika rantai dengan panjang yang sama bersaing untuk seleksi sebagai rantai induk, maka pilihannya akan seri untuk:

    • rantai yang memiliki jumlah rantai samping terbanyak.
    • rantai yang substituennya memiliki angka terendah.
    • rantai memiliki jumlah atom karbon terbesar di rantai samping terkecil.
    • rantai memiliki rantai samping bercabang paling sedikit (grafik memiliki jumlah daun paling sedikit).

Untuk rantai induk, penamaannya adalah:

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

Tidak ada rantai yang lebih panjang dari 12, jadi ini sudah cukup. Untuk sub-rantai itu sama tetapi bukannya 'ane' pada akhirnya kita memiliki 'yl'.

Anda dapat mengasumsikan bahwa Cs berada di kolom ganjil dan binding ( |dan -karakter) adalah 1 panjang antara atom karbon.

Kasus uji:

Memasukkan:

C-C-C-C

Keluaran:

butana

Memasukkan:

C-C-C
  |
  C

Keluaran:

2-metilpropana

Memasukkan:

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

Keluaran:

3-metilheksana

Memasukkan:

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

Keluaran:

3-metilheksana

Memasukkan:

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

Keluaran:

3,4-dimethyl-5-ethylheptane

Sunting: Maaf untuk contoh yang salah. Saya bukan murid yang baik :(. Mereka harus diperbaiki sekarang.

Peter Lenkefi
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Dennis
2
Menurut aturan ini,, 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.).bukankah seharusnya contoh terakhir disebut 3,4- di metil-5-etilheptana? (kami baru memulai kimia organik, saya mungkin salah: P)
NieDzejkob
@NieDzejkob saya setuju, karena ada dua rantai metil.
Jonathan Frech
@NieDzejkob Memang, diperbaiki.
Peter Lenkefi

Jawaban:

18

Python 2 , 1876 1871 1870 1859 1846 1830 1826 1900 1932 1913 1847 1833 1635 1613 1596 byte

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'

Cobalah online!

Nah begitulah. Tentu saja bukan golfiest tetapi berfungsi (saya harap): D

Butuh waktu sekitar 10 jam, mungkin? Mungkin golf terlama saya dalam ukuran dan waktu, dan itu mengatakan sesuatu mengingat saya dulu menggunakan Java D:

Logika:

  1. Konversi dari representasi ASCII ke representasi grafik dengan masing-masing atom karbon sebagai simpul dan setiap ikatan sebagai sisi yang direpresentasikan dalam bentuk kedekatan.
  2. Temukan semua daun; yaitu, simpul dengan hanya satu ikatan. Rantai terpanjang dijamin dari satu ini ke yang lain.
  3. Temukan produk diad dari daun; yaitu, semua pasang node tepi. Lalu, ambil seluruh rantai ini.
  4. Untuk setiap rantai, temukan subchainsnya.
  5. Lakukan hal-hal untuk memilih rantai yang tepat. Jika ada ikatan, maka itu tidak masalah. Fakta menyenangkan: Akan selalu ada dasi karena setiap rantai dihitung dua kali, sekali terbalik.
  6. Cetak dengan benar.

EDIT : Fixed bug di mana ia digunakan untuk menyebabkan kesalahan jika tidak ada rantai samping.

EDIT : Terima kasih kepada MD XF karena memperhatikan beberapa ruang ekstra (lekukan untuk loop).

EDIT : Saya benar-benar lupa tentang awalan untuk memiliki substituen yang sama.

CATATAN : Setiap baris harus memiliki lebar yang sama agar dapat berfungsi. Artinya, ruang trailing diperlukan.

Fakta menyenangkan: sebagian besar hidrokarbon siklik akan ditentukan sebagai "metana"

Fakta menyenangkan: Jika Anda melakukannya C-C-...-C-Cdengan 13 C, itu akan memberi ethane, maka thaneuntuk 14, ropaneuntuk 15, dll.

-79 byte terima kasih kepada Jonathan Frech
-119 byte terima kasih kepada NieDzejkob
-17 byte terima kasih untuk ovs

HyperNeutrino
sumber