Grau de insaturação


11

Grau de insaturação

Este não é um quebra-cabeça de código particularmente difícil - mas estou interessado em ver suas várias maneiras de resolvê-lo.

O grau de insaturação é o número de ligações químicas duplas entre átomos e / ou o número de anéis em um composto químico.

Você receberá a fórmula molecular de um composto químico na forma XaYbZc (onde a, bec são o número de átomos de X, Y ou Z no composto) - a fórmula pode ter qualquer comprimento e conter qualquer elemento químico na tabela periódica (embora outros elementos que não sejam C, H, N, F, Cl, Br, I possam ser ignorados, pois não aparecem na fórmula). O composto conterá pelo menos um átomo de carbono. Você deve calcular e exibir seu grau de insaturação.

Por exemplo, o composto benzeno (foto abaixo) tem uma DoU de 4, pois possui três ligações duplas (mostradas por uma linha dupla entre átomos) e um único anel (um número de átomos conectados em um loop):

anel de benzeno

Conforme definido pelo LibreTexts :

DoU = (2C + 2 + N - X - H) / 2

Onde:

  • C é o número de átomos de carbono
  • N é o número de átomos de nitrogênio
  • X é o número de átomos de halogénio ( F, Cl, Br, I)
  • H é o número de átomos de hidrogênio

Casos de teste:

C6H6 --> 4
C9H2O1 --> 0
C9H9N1O4 --> 6
U1Pt1 --> Not a valid input, no carbon
Na2O1 --> Not a valid input, no carbon
C1H1 --> 1.5, although in practice this would be one, but is a part of a compound rather than a compound in entirety. 
N1H3 would return 0 - though in practice it isn't an organic compound (in other words it contains no carbon) so the formula wouldn't apply and it isn't a valid input

Para uma explicação sobre CH veja aqui

Em essência, você deve identificar se há algum dos elementos acima (C, H, N, F, Cl, Br, I) no composto e, em caso afirmativo, quantos existem. Em seguida, calcule o grau de insaturação usando a fórmula acima.

Somente C, H, N, F, Cl, Br e I são entradas válidas para a fórmula DoU. Para os propósitos deste quebra-cabeça, quaisquer outros elementos podem ser completamente ignorados (por exemplo, se o composto fosse C6H6Mn, o resultado ainda seria 4). Se não houver nenhum dos compostos acima, a resposta seria zero.

Você pode assumir que todas as entradas de compostos são quimicamente possíveis, contêm pelo menos um átomo de carbono e são conhecidas por existir. Se a entrada for inválida, o programa pode gerar 0 ou -1 ou não produzir nenhum resultado.

Regras

Aplicam -se regras e brechas de IO padrão . A entrada deve ser uma sequência padrão e você pode assumir que a entrada não estará vazia. Este é o codegolf - então o código mais curto em bytes vence.


Casos de teste propostos: Óxido de sódio: Na2Oe Metilidino: CHe CCl4He. Esses são alguns casos extremos que podem quebrar algumas soluções. A propósito, não que isso importe para alguém que não seja o Mathematica (provavelmente), mas podemos supor que os compostos (possam) existir?
Stewie Griffin

Eu não entendo C9H2O1 --> 0. Não deveria ser 9? (2*9+2+0-0-2)/2
DLosc

de acordo com o último parágrafo, você quer dizer que o código deve ser capaz de lidar com entradas inválidas? A propósito, é garantido que cada elemento no composto tenha um '1' à direita, como no C1H1?
Keyu Gan

@KeyuGan yes and yes.
Archie Roques

Respostas:


2

JavaScript (ES6), 117 112 bytes

Retorna 0para entradas inválidas.

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,s|=n==2,n>2?3:n],1)*s

Casos de teste

Versão alternativa, 103 bytes

Se a entrada fosse garantida como válida - como a introdução do desafio sugere de maneira enganosa -, poderíamos simplesmente:

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,n>2?3:n],1)

Demo


2

Python 3 , 142 151 148 bytes

import re
l=dict(re.findall("(\D+)(\d+)",input()))
m=lambda k:int(l.get(k,0))
print(m("C")and m("C")+1+(m("N")-sum(map(m,"F I H Cl Br".split())))/2)

Retorna 0 em erro.

Graças a @HyperNeutrino reduzindo os bytes.

Experimente online!


oops - casos de teste atualizados!
Archie Roques


Os casos de teste @HyperNeutrino não eram claros por um tempo. Agora não tem saída na entrada inválida.
MooseOnTheRocks


Bom uso de dictlá!
DLosc

0

Pip , 70 67 bytes

`C\d`Na&1+/2*VaR+XDs._R['C'NC`H|F|I|Cl|Br`].s["+2*"'+'-]RXU.XX"+0*"

Adota a fórmula química como argumento da linha de comando. Saídas 0para entradas inválidas. Experimente online!

Explicação

Usa uma série de substituições regex para transformar a fórmula química em uma fórmula matemática, avalia-a e faz alguns ajustes para obter o valor final.

As substituições (versão ligeiramente não destruída):

aR+XDs._R"C ""+2*"R"N "'+R`(H|F|I|Cl|Br) `'-RXU.XX"+0*"

a                    Cmdline arg
 R+XD                 Replace runs of 1 or more digits (\d+)
     s._               with a callback function that prepends a space
                       (putting a space between each element and the following number)
 R"C "                Replace carbon symbol
      "+2*"            with +2* (add 2* the number of carbon atoms to the tally)
 R"N "                Replace nitrogen symbol
      '+               with + (add the number of nitrogen atoms to the tally)
 R`(H|F|I|Cl|Br) `    Replace hydrogen or halogen symbol
                  '-   with - (subtract the number of atoms from the tally)
 RXU.XX               Replace uppercase letter followed by another char ([A-Z].)
       "+0*"           with +0* (cancel out numbers of all other kinds of atoms)

Avaliamos a string resultante com V. Isso nos dá 2C + N − X − H. Para obter o valor correto, fazemos os seguintes ajustes:

`C\d`Na&1+/2*V...

             V...  Value of expression calculated above
          /2*      multiplied by 1/2
        1+         plus 1
`C\d`Na            Is carbon in the original formula? (i.e. C followed by a digit)
       &           Logical AND: if no carbon, return 0, otherwise return the formula value

0

C (gcc) , 195197 202 bytes

Provavelmente a resposta mais longa.

d,c,b,e,n;f(char*a){for(c=d=0;b=*a;d+=e?e-1?b-66?b-67?0:e-2?0:-n:e-3?0:-n:b-67?b-78?b/70*73/b?-n:0:n:(c=2*n):0)e=*++a>57?*a-108?*a-114?0:3:2:1,a+=e>1,n=strtol(a,&a,10);printf("%.1f",c?d/2.+1:0);}

Experimente online!

Retorna 0 em erro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.