สมการทางเคมีที่บ้าคลั่ง


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


@MtnViewMark มันควรจะเป็นโปรแกรม ควรใช้หนึ่งสมการต่อการวิ่งหนึ่งครั้ง
gthacoder

ตัวอย่างที่สองและสามของคุณผิด ฉันคิดว่าคุณหมายถึงพิมพ์2O2แทน202(สองร้อยและสอง)
r3mainer

@squeamishossifrage โอ้ใช่ แน่ใจ ขอบคุณ. อัปเดตคำถามแล้ว
gthacoder

คำตอบ:


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

@MtnViewMark อย่างแม่นยำมากขึ้นฉันนับอำนาจด้วยแล้วคูณพวกเขาโดยค่าสัมประสิทธิ์กับTr@CoefficientRules Times@@@สำหรับO: 2*2+2*2=4*2สำหรับC: 2*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)

regex-rewriting การแปลงสมการอินพุตเป็นสิ่งที่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)

ฉันแน่ใจว่าจะมีสนามกอล์ฟเพิ่มขึ้นในส่วน regex


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

นี่คือรุ่นที่ไม่ได้เตรียมไว้ในกรณีที่ใคร ๆ ก็อยากติดตาม มันเป็นParsecparser ตามง่าย:

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.