不饱和度


11

不饱和度

这并不是一个特别困难的代码难题-但我很想看到您解决问题的多种方式。

不饱和度是原子之间的双化学键的数目和/或化合物中的环数。

您将以XaYbZc的形式得到化合物的分子式(其中a,b和c是化合物中X,Y或Z的原子数)-分子式可以是任何长度,并且可以包含任何化学元素在元素周期表中(尽管C,H,N,F,Cl,Br以外的元素,我可能会被忽略,因为它们不在公式中显示)。该化合物将包含至少一个碳原子。您必须计算并显示其不饱和度。

例如,化合物苯(如下图所示)的DoU为4,因为它具有三个双键(由原子之间的双线表示)和一个单环(成环连接的多个原子):

苯环

根据LibreTexts的定义:

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

哪里:

  • C 是碳原子数
  • N 是氮原子数
  • X 是卤素原子的数量(FClBrI
  • H 是氢原子数

测试用例:

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

有关CH的说明,请参见此处

本质上,您必须确定化合物中是否存在上述任何元素(C,H,N,F,Cl,Br,I),如果存在,则为多少。然后,使用以上公式计算不饱和度。

对于DoU公式,只有C,H,N,F,Cl,Br和I是有效输入。为了解决这个难题,可以完全忽略其他任何元素(例如,如果化合物为C6H6Mn,则结果仍为4)。如果没有上述化合物,答案将为零。

您可以假定所有输入的化合物在化学上都是可能的,至少包含一个碳原子,并且已知存在。如果输入无效,则程序可能输出0或-1,或者不产生结果。

规则

适用标准IO规则漏洞。输入必须是标准字符串,并且您可以假定输入不会为空。这是codegolf-以字节为单位的最短代码为准。


建议的测试用例:氧化钠:Na2O和亚甲基:CHCCl4He。这些都是极端情况,可能会打破一些解决方案。顺便说一句,这对Mathematica以外的任何人都没有关系(可能),但是我们可以假设化合物(可以)存在吗?
Stewie Griffin

我不明白C9H2O1 --> 0。不应该是9吗?(2*9+2+0-0-2)/2
DLosc

根据上一段,您的意思是代码必须能够处理无效输入吗?顺便说一句,是否可以确保化合物中的每个单个元素都像C1H1那样带有尾随的“ 1”?
Keyu Gan

@KeyuGan是的,是的。
Archie Roques

Answers:


2

的JavaScript(ES6),117个 112字节

返回0无效输入。

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

测试用例

替代版本,103字节

如果输入的内容被保证是有效的-就像挑战性介绍所误导的那样-我们可以这样做:

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)

演示版


2

Python 3中142个151 148字节的

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)

错误返回0。

感谢@HyperNeutrino减少了字节数。

在线尝试!


糟糕-测试案例已更新!
Archie Roques


@HyperNeutrino测试用例有点不清楚。现在在无效输入上没有输出。
MooseOnTheRocks


dict那里很好用!
DLosc

0

70 67字节

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

将化学式作为命令行参数。输出0无效投入。在线尝试!

说明

使用一系列正则表达式替换将化学公式转换为数学公式,对其进行评估,并进行几次调整以获得最终值。

替代品(略有瑕疵的版本):

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)

我们使用来评估结果字符串V。这给了我们2C + N − X − H。为了获得正确的值,我们进行了以下调整:

`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 个字节

可能是最长的答案。

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);}

在线尝试!

错误返回0。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.