미친 화학 방정식


10

사용자로부터 화학 방정식 (공백 없음, 문자 (대문자 및 소문자), 숫자, 괄호 및 수학 기호)을 가져 와서 방정식이 균형을 이루 거나 그렇지 않은 경우 (양수 / 음수 응답 쌍) : 예 / 아니요, 참 / 거짓, 1/0). 알루미늄 (Al), 아르곤, B, 수, C, CL, CR, 구리, 철, H, 그는, K, N, O, S. 그리고 : 짧은 코드 당신이 입력 문자열은 이러한 요소를 포함 할 수 있습니다 가정 할 수 있도록하려면 한 가지 더 : -징후 가있을 수 있습니다 . 수학에 관한 모든 것 : +더하기, -빼기

예 :

입력:

C6H5COOH-O2=7CO2+3H2O

산출:

No

입력:

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

산출:

Yes

입력:

2SO2=2SO4-2O2

산출:

Yes

가장 짧은 코드가 승리합니다.


기능을 찾고 있습니까? 아니면 텍스트 입력을 받아 텍스트 출력을 제공하는 프로그램입니까? 나중에 여러 줄을 처리해야합니까? 또는 런당 하나의 방정식입니까?
MtnViewMark


@MtnViewMark 프로그램으로되어 있습니다. 실행 당 하나의 방정식이 필요합니다.
gthacoder

두 번째와 세 번째 예가 잘못되었습니다. 나는 당신 2O2202(이백 둘) 대신 입력하려고 생각합니다 .
r3mainer

@squeamishossifrage 아, 그래. 확실한. 감사합니다. 질문이 업데이트되었습니다.
gthacoder

답변:


2

매스 매 티카 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"

그릇된

진실

진실

화학식을 다항식으로 취급합니다. 예 :

여기에 이미지 설명을 입력하십시오

그런 다음 계수를 계산합니다.


어떻게 작동합니까? 귀하의 예에서, 각 "변수"의 계수는 0으로 단순화되지 않습니다.
MtnViewMark

@MtnViewMark 더 정확하게 말하면, 거듭 제곱 Tr@CoefficientRules을 곱한 다음에 계수를 곱 Times@@@합니다. 의 경우 O: 2*2+2*2=4*2C: 2*6 = 6*2
ybeltukov

2

파이썬 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

하스켈 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

누구나 따라하고 싶은 경우를 위해 ungolf'd 버전이 있습니다. 간단한 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.