Équations chimiques folles


10

Vous devez obtenir une chaîne d'équation chimique (pas d'espaces, uniquement des lettres (majuscules et minuscules), des chiffres, des crochets et des signes mathématiques) de l'utilisateur et imprimer la réponse si l'équation est équilibrée ou non (toute paire de réponses positives / négatives : Oui / Non, vrai / faux, 1/0). Pour raccourcir le code, vous pouvez supposer que les chaînes d'entrée ne peuvent contenir que ces éléments: Al, Ar, B, Be, C, Cl, Cr, Cu, Fe, H, He, K, N, O, S. Et encore une chose : il pourrait y avoir des -signes. Tout est question de mathématiques: +signifie addition, -signifie soustraction.

Exemples:

Contribution:

C6H5COOH-O2=7CO2+3H2O

Production:

No

Contribution:

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

Production:

Yes

Contribution:

2SO2=2SO4-2O2

Production:

Yes

Le code le plus court gagne.


Cherchez-vous une fonction? Ou un programme qui prend la saisie de texte et donne une sortie de texte? Si ce dernier, doit-il prendre et traiter plusieurs lignes? Ou juste une équation par course?
MtnViewMark


@MtnViewMark Il est censé être un programme. Cela devrait prendre une équation par cycle.
gthacoder

Vos deuxième et troisième exemples sont erronés. Je pense que vous vouliez taper 2O2au lieu de 202(deux cent deux).
r3mainer

@squeamishossifrage Oh, oui. Sûr. Je vous remercie. La question est mise à jour.
gthacoder

Réponses:


2

Mathematica 152

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

Résultat:

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

Faux

Vrai

Vrai

Je traite la formule chimique comme un polynôme, par exemple

entrez la description de l'image ici

Ensuite, je compte juste les coefficients.


Comment ça marche? Dans votre exemple, les coefficients de chaque "variable" ne se simplifient pas à zéro.
MtnViewMark

@MtnViewMark Plus précisément, je compte les puissances avec Tr@CoefficientRulespuis je les multiplie par des coefficients avec Times@@@. Pour O: 2*2+2*2=4*2pour C: 2*6 = 6*2, etc.
ybeltukov

2

Python 2.7, 316 276 caractères

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)

Il fait beaucoup de réécriture regex pour convertir l'équation d'entrée en quelque chose de evalcapable. Il vérifie ensuite l'équation pour chaque élément individuellement.

Par exemple, les équations d'exemple réécrivent dans (la tvariable):

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

Je suis sûr qu'il y a plus de golf sur la partie regex.


2

Haskell, 400 351 308 caractères

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)

Cela pourrait avoir tout le golf hors de lui. Je ne sais pas s'il y a encore 100 51 8 caractères à sauver!

& 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

Voici la version non golfée, au cas où quelqu'un voudrait suivre. Il s'agit d'un Parsecanalyseur basé simple :

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)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.