Persamaan kimia gila

10

Anda harus mendapatkan string persamaan kimia (tanpa spasi, hanya huruf (huruf besar dan kecil), angka, tanda kurung dan matematika) dari pengguna dan mencetak jawabannya jika persamaannya seimbang atau tidak (pasangan jawaban positif / negatif) : Ya / Tidak, benar / salah, 1/0). Untuk mempersingkat kode, Anda dapat mengasumsikan bahwa string input hanya dapat berisi elemen-elemen ini: Al, Ar, B, Be, C, Cl, Cr, Cu, Fe, H, He, K, N, O, S. Dan satu hal lagi : mungkin ada -tanda - tanda. Ini semua tentang matematika: +berarti penambahan, -berarti pengurangan.

Contoh:

Memasukkan:

C6H5COOH-O2=7CO2+3H2O

Keluaran:

No

Memasukkan:

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

Keluaran:

Yes

Memasukkan:

2SO2=2SO4-2O2

Keluaran:

Yes

Kode terpendek menang.

gthacoder
sumber
Apakah Anda mencari fungsi? Atau program yang mengambil input teks dan memberikan output teks? Jika nanti, haruskah mengambil dan memproses beberapa baris? Atau hanya satu persamaan per run?
MtnViewMark
Terkait: Saldo persamaan kimia
Peter Taylor
@MtnViewMark Seharusnya program. Ini harus mengambil satu persamaan per run.
gthacoder
Contoh kedua dan ketiga Anda salah. Saya pikir Anda bermaksud mengetik 2O2bukan 202(dua ratus dua).
r3mainer
@squeamishossifrage Oh, ya. Tentu. Terima kasih. Pertanyaan diperbarui.
gthacoder

Jawaban:

2

Mathematica 152

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

Hasil:

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

Salah

Benar

Benar

Saya memperlakukan rumus kimia sebagai polinomial, misalnya

masukkan deskripsi gambar di sini

Lalu saya hanya menghitung koefisien.

ybeltukov
sumber
Bagaimana cara kerjanya? Dalam contoh Anda, koefisien masing-masing "variabel" tidak disederhanakan menjadi nol.
MtnViewMark
@ MTnViewMark Lebih tepatnya, saya menghitung kekuatan dengan Tr@CoefficientRulesdan kemudian melipatgandakannya dengan koefisien Times@@@. Untuk O: 2*2+2*2=4*2, untuk C: 2*6 = 6*2, dll
ybeltukov
2

Python 2.7, 316 276 karakter

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)

Itu banyak regex-menulis ulang untuk mengubah persamaan input menjadi sesuatu yang evalmampu. Kemudian memeriksa persamaan untuk setiap elemen secara individual.

Misalnya, contoh persamaan ditulis ulang menjadi ( tvariabel):

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

Saya yakin ada lebih banyak golf yang bisa didapat di bagian regex.

Keith Randall
sumber
2

Haskell, 400 351 308 karakter

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)

Ini hanya bisa membuat semua golf terjepit. Saya tidak tahu apakah ada 100 51 8 karakter yang harus diselamatkan!

& 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

Berikut adalah versi yang tidak diklik, siapa tahu ada yang mau mengikuti. Ini adalah Parsecpengurai berbasis sederhana :

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)
MtnViewMark
sumber