疯狂的化学方程式


10

您应该从用户那里获得一串化学方程式(没有空格,只有字母(大写和小写),数字,方括号和数学符号),并且在方程式是否平衡时打印答案(任何一对正负答案) :是/否,是/否,1/0)。为了使代码更短,您可以假设输入字符串只能包含以下元素:Al,Ar,B,Be,C,Cl,Cr,Cu,Fe,H,He,K,N,O,S。还有另外一点:可能有-迹象。这全都与数学有关:+表示加法,-表示减法。

例子:

输入:

C6H5COOH-O2=7CO2+3H2O

输出:

No

输入:

2Fe(CN)6+2SO2+202=Fe2(SO4)2+6C2N2

输出:

Yes

输入:

2SO2=2SO4-2O2

输出:

Yes

最短的代码获胜。


您在寻找功能吗?还是接受文本输入并提供文本输出的程序?如果是更高版本,是否需要处理多个行?还是每次运行只有一个方程?
MtnViewMark 2014年


@MtnViewMark应该是一个程序。每次运行应采用一个方程式。
gthacoder 2014年

您的第二个和第三个示例是错误的。我认为您的意思是键入2O2而不是202(202)。
r3mainer 2014年

@squeamishossifrage哦,是的。当然。谢谢。问题已更新。
gthacoder 2014年

Answers:


2

Mathematica 152

f=Times@@@Tr@CoefficientRules@ToExpression@(r=StringReplace)[r[
#<>")",{"="->"-(",x:_?LetterQ|")"~~y_?DigitQ:>x<>"^"<>y}],x_?UpperCaseQ:>" "<>x]⋃{}=={0}&

结果:

f@"C6H5COOH-O2=7CO2+3H2O"
f@"2Fe(CN)6+2SO2+2O2=Fe2(SO4)2+6C2N2"
f@"2SO2=2SO4-2O2"

真正

真正

我将化学式视为多项式,例如

在此处输入图片说明

然后我只计算系数。


这是如何运作的?在您的示例中,每个“变量”的系数都不会简化为零。
MtnViewMark 2014年

@MtnViewMark更精确地讲,我用计算幂,Tr@CoefficientRules然后用乘以系数Times@@@。对于O2*2+2*2=4*2,为C2*6 = 6*2
ybeltukov

2

Python 2.7、316 276个字符

import re
r=re.sub
x='(^|[=+-])'
y=r'\1+\2'
z='(\w)([A-Z(])'
t=r('=','==',r(z,y,r(z,y,r('([A-Za-z)])(\d)',r'\1*\2',r('([=+-]|$)',r')\1',r(x+'(\d+)',r'\1\2*(',r(x+'([A-Z])',r'\1(\2',raw_input())))))))
E=re.findall('[A-Za-z]+',t)
print all(eval(t,{f:f==e for f in E})for e in E)

它进行了大量的正则表达式重写,以将输入方程式转换为可转换的形式eval。然后,它会分别检查每个元素的方程式。

例如,示例方程式重写为(t变量):

(C*6+H*5+C+O+O+H)-(O*2)==7*(C+O*2)+3*(H*2+O)
2*(Fe+(C+N)*6)+2*(S+O*2)+2*(O*2)==(Fe*2+(S+O*4)*2)+6*(C*2+N*2)
2*(S+O*2)==2*(S+O*4)-2*(O*2)

我确信正则表达式部分还有更多的高尔夫用途。


2

Haskell中,400个 351 308字符

import Data.List
import Text.Parsec
(&)=fmap
r=return
s=string
l f b=(>>=(&b).f)
x=(=<<).replicate
m=sort&chainl1(l x(concat&many1(l(flip x)n i))n)((s"+">>r(++))<|>(s"-">>r(\\)))
i=between(s"(")(s")")m<|>(:[])&(l(:)(many lower)upper)
n=option 1$read&many1 digit
main=getContents>>=parseTest(l(==)(s"=">>m)m)

这可能会使所有高尔夫球都挤走了。我不知道是否还有100 51 8个字符要保存!

& echo 'C6H5COOH-O2=7CO2+3H2O' | runhaskell Chemical.hs
False

& echo '2Fe(CN)6+2SO2+2O2=Fe2(SO4)2+6C2N2' | runhaskell Chemical.hs
True

& echo '2SO2=2SO4-2O2' | runhaskell Chemical.hs
True

如果有人想跟进,这是非高尔夫球的版本。这是一个Parsec基于简单的解析器:

import Control.Applicative ((<$>), (<*>))
import Data.List
import Text.Parsec
import Text.Parsec.String (Parser)

type Atom = String

{- golf'd as x -}
multiple :: Int -> [Atom] -> [Atom]
multiple n = concat . replicate n

{- golf'd as m -}
chemicals :: Parser [Atom]
chemicals = sort <$> chainl1 molecules op
  where
    op :: Eq a => Parser ([a] -> [a] -> [a])
    op = (char '+' >> return (++))
     <|> (char '-' >> return (\\))

    molecules :: Parser [Atom]
    molecules = multiple <$> number <*> terms

    terms :: Parser [Atom]
    terms = concat <$> many1 term

    term :: Parser [Atom]
    term = flip multiple <$> item <*> number

{- gofl'd as i -}
item :: Parser [Atom]
item = between (char '(') (char ')') chemicals
   <|> (:[]) <$> atom
  where
    atom :: Parser Atom
    atom = (:) <$> upper <*> many lower

{- gofl'd as n -}
number :: Parser Int
number = option 1 $ read <$> many1 digit

{- gofl'd as main -}
main :: IO ()
main = getContents >>= parseTest chemEquality
  where
    chemEquality :: Parser Bool
    chemEquality = (==) <$> chemicals <*> (char '=' >> chemicals)
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.