Phương trình hóa học điên


10

Bạn nên nhận chuỗi phương trình hóa học (không có khoảng trắng, chỉ có chữ cái (chữ hoa và chữ thường), số, dấu ngoặc và dấu toán học) từ người dùng và in câu trả lời nếu phương trình có cân bằng hay không (bất kỳ cặp câu trả lời dương / âm nào : Có / Không, đúng / sai, 1/0). Để làm cho mã ngắn hơn, bạn có thể giả sử rằng các chuỗi đầu vào chỉ có thể chứa các phần tử sau: Al, Ar, B, Be, C, Cl, Cr, Cu, Fe, H, He, K, N, O, S. Và một điều nữa : có thể có -dấu hiệu. Đó là tất cả về toán học: +-nghĩa là phép cộng , có nghĩa là phép trừ.

Ví dụ:

Đầu vào:

C6H5COOH-O2=7CO2+3H2O

Đầu ra:

No

Đầu vào:

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

Đầu ra:

Yes

Đầu vào:

2SO2=2SO4-2O2

Đầu ra:

Yes

Mã ngắn nhất sẽ thắng.


Bạn đang tìm kiếm một chức năng? Hoặc một chương trình có nhập văn bản và cung cấp đầu ra văn bản? Nếu sau này, nó có nên và xử lý nhiều dòng? Hay chỉ một phương trình cho mỗi lần chạy?
MtnViewMark


@MtnViewMark Nó được coi là một chương trình. Nó sẽ mất một phương trình cho mỗi lần chạy.
gthacoder

Ví dụ thứ hai và thứ ba của bạn là sai. Tôi nghĩ bạn có ý định gõ 2O2thay vì 202(hai trăm hai).
r3mainer

@squeamishossifrage Ồ, vâng. Chắc chắn rồi. Cảm ơn bạn. Câu hỏi được cập nhật.
gthacoder

Câu trả lời:


2

Toán học 152

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

Kết quả:

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

Sai

Thật

Thật

Tôi coi công thức hóa học là một đa thức, vd

nhập mô tả hình ảnh ở đây

Sau đó tôi chỉ đếm các hệ số.


Làm thế nào mà làm việc? Trong ví dụ của bạn, các hệ số của từng "biến" không đơn giản hóa thành không.
MtnViewMark

@MtnViewMark Chính xác hơn, tôi đếm các quyền hạn Tr@CoefficientRulesvà sau đó nhân chúng với các hệ số với Times@@@. Dành cho O: 2*2+2*2=4*2, cho C: 2*6 = 6*2, v.v.
ybeltukov

2

Python 2.7, 316 276 ký tự

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)

Nó thực hiện rất nhiều cách viết lại để chuyển đổi phương trình đầu vào thành một cái gì đó evalcó thể. Sau đó, nó kiểm tra phương trình cho từng phần tử riêng lẻ.

Ví dụ, các phương trình ví dụ viết lại thành ( tbiến):

(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)

Tôi chắc chắn rằng có nhiều golf hơn để có phần regex.


2

Haskell, 400 351 308 ký tự

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)

Điều này chỉ có thể có tất cả các golf vắt ra khỏi nó. Tôi không biết có còn 100 51 8 ký tự nữa không!

& 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

Đây là phiên bản ungolf'd, trong trường hợp bất cứ ai muốn theo cùng. Nó là một Parsectrình phân tích cú pháp dựa trên đơn giản :

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.