Çılgın kimyasal denklemler


10

Kullanıcıdan kimyasal denklem dizesi (boşluk yok, sadece harfler (büyük harf ve küçük harf), sayılar, köşeli parantezler ve matematik işaretleri) almalı ve denklem dengeli ise ya da değilse (herhangi bir pozitif / negatif cevap çifti) cevabı yazdırmalısınız. : Evet / Hayır, doğru / yanlış, 1/0). Kodu kısaltmak için giriş dizelerinin yalnızca şu öğeleri içerebileceğini varsayabilirsiniz: Al, Ar, B, Be, C, Cl, Cr, Cu, Fe, H, He, K, N, O, S. Ve bir şey daha : -işaretler olabilir . Her şey matematikle ilgili: +toplama, -çıkarma anlamına gelir.

Örnekler:

Giriş:

C6H5COOH-O2=7CO2+3H2O

Çıktı:

No

Giriş:

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

Çıktı:

Yes

Giriş:

2SO2=2SO4-2O2

Çıktı:

Yes

En kısa kod kazanır.


Bir işlev mi arıyorsunuz? Veya metin girişi alan ve metin çıkışı veren bir program? Daha sonra, birden fazla satır almalı ve işlemeli mi? Veya çalışma başına sadece bir denklem mi?
MtnViewMark


@MtnViewMark Bir program olması gerekiyordu. Her çalışma için bir denklem almalıdır.
gthacoder

İkinci ve üçüncü örnekleriniz yanlış. Ben yazdığınız anlamına düşünüyorum 2O2yerine 202(iki yüz ve iki).
r3mainer

@squeamishossifrage Oh, evet. Elbette. Teşekkür ederim. Soru güncellendi.
gthacoder

Yanıtlar:


2

Mathematica 152

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

Sonuç:

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

Yanlış

Doğru

Doğru

Kimyasal formüle polinom gibi davranıyorum, örn.

resim açıklamasını buraya girin

Sonra sadece katsayıları sayıyorum.


Bu nasıl çalışıyor? Örneğinizde, her bir "değişken" in katsayıları sıfıra basitleştirilmez.
MtnViewMark

@MtnViewMark Daha doğrusu, güçleri sayıyorum Tr@CoefficientRulesve sonra katsayılarla çarpıyorum Times@@@. İçin O:, 2*2+2*2=4*2için C:, 2*6 = 6*2vb.
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)

Giriş denklemini evalmümkün olan bir şeye dönüştürmek için birçok regex-yeniden yazma işlemi yapar . Daha sonra her eleman için denklemi ayrı ayrı kontrol eder.

Örneğin, örnek denklemler ( tdeğişken) olarak yeniden yazar :

(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 kısmında daha fazla golf var eminim.


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)

Bu sadece tüm golf dışarı sıkılmış olabilir. Kaydedilecek başka 100 51 8 karakter olup olmadığını bilmiyorum !

& 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

İşte herkesin takip etmek istemesi durumunda ungolf'd versiyonu. Basit Parsectabanlı bir ayrıştırıcıdır:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.