Attribution d'un nom aux chaînes de carbone non cycliques


30

(Je ne suis pas chimiste! Je peux me tromper sur certaines choses, j'écris ce que j'ai appris au lycée)

Les atomes de carbone ont un attribut spécial: ils peuvent se lier à 4 autres atomes (ce qui n'est pas si spécial) et ils restent stables même en longues chaînes, ce qui est très unique. Parce qu'ils peuvent être enchaînés et combinés de différentes manières, nous avons besoin d'une sorte de convention de dénomination pour les nommer.

Il s'agit de la plus petite molécule que nous puissions fabriquer:

CH4

Ça s'appelle du méthane. Il se compose d'un seul carbone et de 4 atomes d'hydrogène. Le suivant est:

CH3 - CH3

C'est ce qu'on appelle l'éthane. Il est composé de 2 atomes de carbone et 6 atomes d'hydrogène.

Les 2 suivants sont:

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

Ce sont le propane et le butane. Les problèmes commencent avec les chaînes à 4 atomes de carbone, car il peut être construit de 2 manières différentes. L'un est illustré ci-dessus et l'autre est:

CH3 - CH - CH3
       |
      CH3

Ce n'est évidemment pas la même chose que l'autre. Le nombre d'atomes et les liaisons sont différents. Bien sûr, le simple fait de plier les fixations et de faire tourner la molécule ne la rendra pas différente! Donc ça:

CH3 - CH2 - CH2 - CH3

Et ça:

CH3 - CH2
       |
CH3 - CH2

Sont les mêmes (si vous êtes dans la théorie des graphes, vous pouvez dire que s'il y a isomorphisme entre 2 molécules; ce sont les mêmes). Désormais, je n'écrirai plus les atomes d'hydrogène car ils ne sont pas indispensables à ce challenge.

Comme vous détestez la chimie organique et que vous avez beaucoup d'atomes de carbone différents à nommer, vous décidez d'écrire un programme qui le fait pour vous. Vous n'avez pas trop d'espace sur votre disque dur, donc le programme doit être aussi petit que possible.

Le défi

Écrivez un programme qui prend un texte sur plusieurs lignes en entrée (une chaîne de carbone) et sort le nom de la chaîne de carbone. L'entrée ne contiendra que des espaces, des caractères «c» majuscules et «|» et «-» qui représente une liaison. La chaîne d'entrée ne contiendra jamais de cycles! Exemple:

Contribution:

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

Sortie:

4-éthyl-2-méthylhexane

Toute sortie est acceptable tant qu'elle est lisible par l'homme et essentiellement la même (vous pouvez donc utiliser différents séparateurs par exemple si vous le souhaitez).

La convention de dénomination:

(Voir: Règles IUPAC )

  1. Identifiez la chaîne de carbone la plus longue. Cette chaîne est appelée la chaîne parente.

  2. Identifiez tous les substituants (groupes issus de la chaîne parente).

  3. Numérotez les carbones de la chaîne parente de l'extrémité qui donne aux substituants les nombres les plus bas. Lorsque l'on compare une série de nombres, la série qui est la "plus basse" est celle qui contient le plus petit nombre à l'occasion de la première différence. Si deux chaînes latérales ou plus sont dans des positions équivalentes, attribuez le numéro le plus bas à celui qui viendra en premier dans le nom.

  4. Si le même substituant apparaît plus d'une fois, l'emplacement de chaque point sur lequel le substituant apparaît est donné. De plus, le nombre de fois où le groupe substituant apparaît est indiqué par un préfixe (di, tri, tétra, etc.).

  5. S'il existe deux ou plusieurs substituants différents, ils sont répertoriés par ordre alphabétique en utilisant le nom de la base (ignorez les préfixes). Le seul préfixe utilisé lors de la mise en ordre alphabétique des substituants est l'iso comme l'isopropyle ou l'isobutyle. Les préfixes sec- et tert- ne sont pas utilisés pour déterminer l'ordre alphabétique, sauf lorsqu'ils sont comparés les uns aux autres.

  6. Si des chaînes de longueur égale sont en compétition pour la sélection en tant que chaîne parente, le choix se fait en série pour:

    • la chaîne qui a le plus grand nombre de chaînes latérales.
    • la chaîne dont les substituants ont le plus petit nombre.
    • la chaîne ayant le plus grand nombre d'atomes de carbone dans la plus petite chaîne latérale.
    • la chaîne ayant les chaînes latérales les moins ramifiées (un graphique ayant le moins de feuilles).

Pour la chaîne parente, la dénomination est:

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

Aucune chaîne ne dépassera 12, ce sera donc suffisant. Pour les sous-chaînes, c'est la même chose, mais au lieu de «ane» à la fin, nous avons «yl».

Vous pouvez supposer que les Cs sont dans les colonnes impaires et que les liaisons ( |et les -caractères) sont longues de 1 entre les atomes de carbone.

Cas de test:

Contribution:

C-C-C-C

Sortie:

butane

Contribution:

C-C-C
  |
  C

Sortie:

2-méthylpropane

Contribution:

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

Sortie:

3-méthylhexane

Contribution:

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

Sortie:

3-méthylhexane

Contribution:

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

Sortie:

3,4-diméthyl-5-éthylheptane

Edit: Désolé pour les mauvais exemples. Je n'étais pas un bon élève :(. Ils devraient être corrigés maintenant.


Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
Dennis

2
Selon cette règle, 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.).le dernier exemple ne devrait-il pas être appelé 3,4- di méthyl-5-éthylheptane? (nous commençons à peine la chimie organique, je me trompe peut-être: P)
NieDzejkob

@NieDzejkob Je serais d'accord, car il y a deux chaînes méthyle.
Jonathan Frech

@NieDzejkob En effet, corrigé.
Peter Lenkefi

Réponses:


18

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

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'

Essayez-le en ligne!

Et bien voilà. Certainement pas le plus golfique mais ça marche (j'espère): D

Ça m'a pris environ 10 heures, peut-être? Probablement mon plus long golf en taille et en temps, et cela veut dire quelque chose étant donné que j'utilisais Java D:

Logique:

  1. Convertissez de la représentation ASCII en représentation graphique avec chaque atome de carbone en tant que nœud et chaque liaison en tant que bord représenté sous forme d'adjacence.
  2. Trouvez toutes les feuilles; c'est-à-dire des nœuds avec une seule liaison. La chaîne la plus longue est garantie d'être de l'un à l'autre.
  3. Trouvez le produit dyadique des feuilles; c'est-à-dire toutes les paires de nœuds de bord. Ensuite, prenez la longueur de toutes ces chaînes.
  4. Pour chaque chaîne, retrouvez ses sous-chaînes.
  5. Faites des trucs pour choisir la bonne chaîne. S'il y a des liens, cela n'a pas vraiment d'importance. Fait amusant: il y aura toujours une égalité car chaque chaîne est comptée deux fois, une fois en sens inverse.
  6. Imprimez-le correctement.

EDIT : correction d'un bug qui causait des erreurs s'il n'y avait pas de chaînes latérales.

EDIT : Merci à MD XF d'avoir remarqué quelques espaces supplémentaires (indentation pour la boucle for).

EDIT : J'ai complètement oublié le préfixe pour avoir le même substituant.

REMARQUE : chaque ligne doit avoir la même largeur pour que cela fonctionne. Autrement dit, des espaces de fin sont requis.

Fait amusant: la plupart des hydrocarbures cycliques seront déterminés comme du «méthane»

Fait amusant: si vous le faites C-C-...-C-Cavec 13 C, cela donnera ethane, puis thanepour 14, ropanepour 15, etc.

-79 octets grâce à Jonathan Frech
-119 octets grâce à NieDzejkob
-17 octets grâce aux ovs

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.