Denominazione di catene di carbonio non cicliche


30

(Non sono un chimico! Potrei sbagliarmi su alcune cose, sto scrivendo quello che ho imparato al liceo)

Gli atomi di carbonio hanno un attributo speciale: possono legarsi ad altri 4 atomi (che non è così speciale) e rimangono stabili anche nelle lunghe catene, il che è davvero unico. Poiché possono essere concatenati e combinati in molti modi diversi, abbiamo bisogno di una sorta di convenzione di denominazione per nominarli.

Questa è la molecola più piccola che possiamo fare:

CH4

Si chiama metano. È costituito da un solo carbonio e 4 atomi di idrogeno. Il prossimo è:

CH3 - CH3

Questo si chiama etano. È composto da 2 atomi di carbonio e 6 di idrogeno.

I prossimi 2 sono:

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

Sono propano e butano. I problemi iniziano con le catene con 4 atomi di carbonio, in quanto possono essere costruite in 2 modi diversi. Uno è mostrato sopra e l'altro è:

CH3 - CH - CH3
       |
      CH3

Questo ovviamente non è uguale all'altro. Il numero di atomi e legami sono diversi. Ovviamente solo piegare i legami e ruotare la molecola non la renderà diversa! Così questo:

CH3 - CH2 - CH2 - CH3

E questo:

CH3 - CH2
       |
CH3 - CH2

Sono gli stessi (se ti piace la teoria dei grafi, puoi dire che se c'è isomorfismo tra 2 molecole; sono le stesse). D'ora in poi non scriverò gli atomi di idrogeno in quanto non sono essenziali per questa sfida.

Dato che odi la chimica organica e hai molti atomi di carbonio diversi da nominare, decidi di scrivere un programma che fa questo per te. Non hai troppo spazio sul tuo disco rigido, quindi il programma deve essere il più piccolo possibile.

La sfida

Scrivi un programma che includa un testo a più righe come input (una catena di carbonio) e produca il nome della catena di carbonio. L'input conterrà solo spazi, caratteri "c" maiuscoli e "|" e '-' che rappresenta un'associazione. La catena di input non conterrà mai cicli! Esempio:

Ingresso:

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

Produzione:

4-etil-2-metilesano

Qualsiasi output è accettabile purché sia ​​leggibile dall'uomo ed essenzialmente lo stesso (quindi è possibile utilizzare diversi separatori, ad esempio, se lo si desidera).

La convenzione di denominazione:

(Vedi: regole IUPAC )

  1. Individua la catena di carbonio più lunga. Questa catena è chiamata catena padre.

  2. Identificare tutti i sostituenti (gruppi aggiunti dalla catena madre).

  3. Numera i carboni della catena madre dall'estremità che fornisce ai sostituenti il ​​numero più basso. Quando si confrontano una serie di numeri, la serie che è il "più basso" è quella che contiene il numero più basso in occasione della prima differenza. Se due o più catene laterali si trovano in posizioni equivalenti, assegnare il numero più basso a quello che verrà per primo nel nome.

  4. Se lo stesso sostituente si verifica più di una volta, viene indicata la posizione di ciascun punto in cui si trova il sostituente. Inoltre, il numero di volte in cui si verifica il gruppo sostituente è indicato da un prefisso (di, tri, tetra, ecc.).

  5. Se ci sono due o più sostituenti diversi, questi sono elencati in ordine alfabetico usando il nome di base (ignora i prefissi). L'unico prefisso che viene usato quando si mettono i sostituenti in ordine alfabetico è iso come in isopropyl o isobutyl. I prefissi sec- e tert- non vengono utilizzati per determinare l'ordine alfabetico, tranne se confrontati tra loro.

  6. Se catene di uguale lunghezza sono in competizione per la selezione come catena madre, la scelta passa in serie a:

    • la catena che ha il maggior numero di catene laterali.
    • la catena i cui sostituenti hanno il numero più basso.
    • la catena che ha il maggior numero di atomi di carbonio nella catena laterale più piccola.
    • la catena con le catene laterali meno ramificate (un grafico con il minor numero di foglie).

Per la catena padre, la denominazione è:

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

Nessuna catena sarà più lunga di 12, quindi questo sarà sufficiente. Per le sotto-catene è lo stesso ma invece di "ane" alla fine abbiamo "yl".

Puoi presumere che le Cs siano nelle colonne dispari e che le associazioni ( |e i -caratteri) siano lunghe 1 tra gli atomi di carbonio.

Casi test:

Ingresso:

C-C-C-C

Produzione:

butano

Ingresso:

C-C-C
  |
  C

Produzione:

2-metilpropano

Ingresso:

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

Produzione:

3-metilesano

Ingresso:

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

Produzione:

3-metilesano

Ingresso:

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

Produzione:

3,4-dimetil-5-ethylheptane

Modifica: scusate gli esempi sbagliati. Non ero un bravo studente :(. Dovrebbero essere riparati ora.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Dennis,

2
Secondo questa regola, 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.).l'ultimo esempio non dovrebbe essere chiamato 3,4- di metil-5-etilesano? (stiamo iniziando la chimica organica, potrei sbagliarmi: P)
NieDzejkob,

@NieDzejkob Sono d'accordo, poiché ci sono due catene metiliche.
Jonathan Frech,

@NieDzejkob Effettivamente, risolto.
Peter Lenkefi,

Risposte:


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'

Provalo online!

Bene, eccoti. Certamente non il più golfistico ma funziona (spero): D

Mi ci sono voluti circa 10 ore, forse? Probabilmente il mio golf più lungo sia in termini di dimensioni che di tempo, e questo sta dicendo qualcosa considerando che usavo Java D:

Logica:

  1. Converti dalla rappresentazione ASCII in rappresentazione grafica con ciascun atomo di carbonio come nodo e ogni legame come un bordo rappresentato in forma di adiacenza.
  2. Trova tutte le foglie; cioè nodi con un solo legame. La catena più lunga è garantita da uno di questi all'altro.
  3. Trova il prodotto diadico delle foglie; cioè, tutte le coppie di nodi di bordo. Quindi, prendi la lunghezza di tutte queste catene.
  4. Per ogni catena, trova le sue catene secondarie.
  5. Fai cose per scegliere la catena giusta. Se ci sono legami, non importa. Curiosità: ci sarà sempre un pareggio perché ogni catena viene contata due volte, una volta al contrario.
  6. Stampalo correttamente.

EDIT : corretto bug in cui veniva utilizzato per causare errori se non c'erano catene laterali.

EDIT : grazie a MD XF per aver notato alcuni spazi extra (rientro per il ciclo for).

EDIT : ho completamente dimenticato il prefisso per avere lo stesso sostituente.

NOTA : ogni linea deve avere la stessa larghezza per funzionare. Cioè, sono richiesti spazi finali.

Curiosità: la maggior parte degli idrocarburi ciclici sarà determinata come "metano"

Curiosità: se lo fai C-C-...-C-Ccon 13 C, ti darà ethane, quindi thaneper 14, ropaneper 15, ecc.

-79 byte grazie a Jonathan Frech
-119 byte grazie a NieDzejkob
-17 byte grazie a ovs

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.