Döngüsel olmayan karbon zincirlerinin isimlendirilmesi


30

(Ben kimyacı değilim! Bazı şeyler yanılıyor olabilir, lisede öğrendiklerimi yazıyorum)

Karbon atomlarının özel bir niteliği vardır: Diğer 4 atomu (bu özel olmayan) bağlayabilirler ve çok benzersiz olan uzun zincirlerde bile kararlı kalırlar. Çok farklı şekillerde zincirlenip birleştirilebildiklerinden, bunları adlandırmak için bir tür adlandırma kuralına ihtiyacımız var.

Bu yapabileceğimiz en küçük molekül:

CH4

Buna metan denir. Sadece bir karbon ve 4 hidrojen atomundan oluşur. Bir sonraki:

CH3 - CH3

Buna etan denir. 2 karbon ve 6 hidrojen atomundan oluşur.

Sonraki 2:

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

Propan ve bütandırlar. Problemler, 2 farklı şekilde inşa edilebildiği için 4 karbon atomlu zincirlerle başlar. Biri yukarıda gösterilmiş, diğeri ise:

CH3 - CH - CH3
       |
      CH3

Bu tabii ki diğeri ile aynı değil. Atom sayısı ve bağlanma farklıdır. Elbette sadece bağları katlamak ve molekülü döndürmek onu farklı kılmaz! Yani bu:

CH3 - CH2 - CH2 - CH3

Ve bu:

CH3 - CH2
       |
CH3 - CH2

Aynı (Eğer grafik teorisindeyseniz, 2 molekül arasında izomorfizm varsa; bunların aynı olduğunu söyleyebilirsiniz). Bundan böyle hidrojen atomlarını bu meydan okuma için gerekli olmadıklarından yazmayacağım.

Organik kimyadan nefret ettiğiniz ve adlandırılacak çok sayıda farklı karbon atomuna sahip olduğunuzdan, bunu sizin için yapan bir program yazmaya karar veriyorsunuz. Sabit diskinizde tho üzerinde fazla yer yok, bu nedenle program mümkün olduğunca küçük olmalıdır.

Meydan okuma

Çok satırlı bir metni girdi (karbon zinciri) olarak alan ve karbon zincirinin adını çıkaran bir program yazın. Girdi yalnızca boşluk, büyük harf 'c' karakterleri ve '|' ve bir bağlayıcıyı temsil eden '-'. Giriş zinciri asla döngü içermeyecek! Örnek:

Giriş:

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

Çıktı:

4-etil-2-metılhekzan

Herhangi bir çıktı, insan tarafından okunabilir ve esasen aynı olduğu sürece kabul edilebilir (bu nedenle örneğin isterseniz farklı ayırıcılar kullanabilirsiniz).

Adlandırma kuralı:

(Bkz: IUPAC kuralları )

  1. En uzun karbon zincirini tanımlayın. Bu zincire ana zincir denir.

  2. Tüm sübstitüentleri (ana zincirden ekleyen gruplar) tanımlayın.

  3. Ana zincirin karbonlarını, ikame edicilere en düşük sayıları veren uçtan sayınız. Bir sayı dizisini karşılaştırırken, "en düşük" olan seri, ilk fark sırasında en düşük sayıyı içeren sayıdır. İki veya daha fazla yan zincir eşdeğer konumdaysa, en düşük sayıyı adın başında gelecek olana verin.

  4. Aynı ikame birden fazla meydana gelirse, ikame maddesinin oluştuğu her bir noktanın konumu verilir. Ek olarak, ikame grubunun meydana gelme sayısı bir önek ile gösterilir (di, tri, tetra, vb.).

  5. İki veya daha fazla farklı ikame edici varsa, baz ismi kullanılarak alfabetik olarak sıralanırlar (önekleri yok sayarlar). İkame edicileri alfabetik sıraya koyarken kullanılan tek ön izopropil veya izobütil'deki iso'dur. Sec- ve tert- önekleri, birbirleriyle karşılaştırılmadıkça, alfabetik sıra belirlenmesinde kullanılmaz.

  6. Eşit uzunluktaki zincirler ana zincir olarak seçim için yarışıyorsa, seçim seri olarak:

    • en fazla yan zincir zincirine sahip zincir.
    • ikame edicileri en düşük sayılara sahip olan zincirdir.
    • en küçük yan zincirde en fazla karbon atomuna sahip zincir.
    • en az dallı yan zincire sahip zincir (en az yaprak sayısına sahip bir grafik).

Ana zincir için adlandırma:

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

Hiçbir zincir 12'den uzun olmayacak, bu yeterli olacaktır. Alt zincirler için aynıdır ancak sonunda 'ane' yerine 'yl' vardır.

CS 'nin tek sütunlarda olduğunu ve bağlanmaların ( |ve -karakterlerin) karbon atomları arasında 1 uzun olduğunu varsayabilirsiniz .

Test durumları:

Giriş:

C-C-C-C

Çıktı:

bütan

Giriş:

C-C-C
  |
  C

Çıktı:

2-metilpropan

Giriş:

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

Çıktı:

3-metılhekzan

Giriş:

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

Çıktı:

3-metılhekzan

Giriş:

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

Çıktı:

3,4-dimetil-5-ethylheptane

Düzenleme: Yanlış örnekler için özür dilerim. İyi bir öğrenci değildim :(. Şimdi düzeltilmeleri gerekiyor.


Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı .
Dennis

2
Bu kurala göre 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.)., son örneğe 3,4 - di metil-5-etilheptan denilmeli mi? (Sadece organik kimyaya başlıyoruz, yanlış olabilirim: P)
NieDzejkob

@NieDzejkob İki metil zinciri olduğu için aynı fikirdeyim.
Jonathan Frech

@NieDzejkob Gerçekten, sabit.
Peter Lenkefi

Yanıtlar:


18

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

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'

Çevrimiçi deneyin!

İyi gidiyorsun. Kesinlikle golf değil ama işe yarıyor (umarım): D

Belki de yaklaşık 10 saat sürdü? Muhtemelen hem büyüklük hem de zamandaki en uzun golf'üm ve Java D'yi kullandığımı düşünen bir şey söylüyor:

Mantık:

  1. ASCII temsilinden, her bir karbon atomunun bir düğüm olarak ve her bir bağın bitişik biçimde temsil edilen bir kenar olarak grafik temsiline dönüştürülmesi.
  2. Tüm yaprakları bul; yani, sadece bir bağ ile düğümler. En uzun zincirin bunlardan birinden diğerine olması garanti edilir.
  3. Yaprakların didik ürününü bulun; yani, tüm kenar düğüm çiftleri. Ardından, tüm bu zincirlerin uzunluğunu alın.
  4. Her zincir için alt zincirlerini bulun.
  5. Doğru zinciri seçmek için şeyler yapın. Eğer bağlar varsa, o zaman önemli değil. Eğlenceli gerçek: Her zaman bir bağ olacak, çünkü her zincir bir kez ters, iki kez sayıldı.
  6. Düzgün yazdırın.

EDIT : Yan zincir yoksa hatalara neden olduğu yerdeki hata düzeltildi.

EDIT : Birkaç ekstra boşluk fark ettiğin için MD XF sağolsun (for loop için girinti).

EDIT : Aynı ikame ediciye sahip olmanın önekini tamamen unuttum.

NOT : Bunun çalışması için her satırın aynı genişlikte olması gerekir. Yani, takip eden boşluklar gereklidir.

Eğlenceli gerçek: çoğu döngüsel hidrokarbon "metan" olarak belirlenecek

Eğlenceli gerçek: Eğer C-C-...-C-C13 Cs yaparsanız , o ethanezaman thane14, ropane15, vb.

-79 byte Jonathan Frech
sayesinde -119 byte NieDzejkob sayesinde
-17 byte ovs sayesinde

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.