Guest User

Untitled

a guest
Dec 16th, 2017
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.76 KB | None | 0 0
  1. Al+Fe2O4->Fe+Al2O3
  2.  
  3. 2Al+Fe2O3->2Fe+Al2O3
  4.  
  5. 40Al+20Fe2O3->40Fe+20Al2O3
  6.  
  7. Nope!
  8.  
  9. Pb->Au
  10.  
  11. C7H16+O2->CO2+H2O
  12. C7H16+11O2->7CO2+8H2O
  13.  
  14. Al+Fe2O3->Fe+Al2O3
  15. 2Al+Fe2O3->2Fe+Al2O3
  16.  
  17. Pb->Au
  18. Nope!
  19.  
  20. // element use table, then once parsed reused as molecule weights
  21. u,t[99];
  22.  
  23. // molecules
  24. char*s,*m[99]; // name and following separator
  25. c,v[99][99]; // count-1, element vector
  26.  
  27. i,j,n;
  28.  
  29. // brute force solver, n==0 upon solution - assume at most 30 of each molecule
  30. b(k){
  31. if(k<0)for(n=j=0;!n&&j<u;j++)for(i=0;i<=c;i++)n+=t[i]*v[i][j]; // check if sums to zero
  32. else for(t[k]=0;n&&t[k]++<30;)b(k-1); // loop through all combos of weights
  33. }
  34.  
  35. main(int r,char**a){
  36. // parse
  37. for(s=m[0]=a[1];*s;){
  38. // parse separator, advance next molecule
  39. if(*s==45)r=0,s++;
  40. if(*s<65)m[++c]=++s;
  41. // parse element
  42. j=*s++;
  43. if(*s>96)j=*s+++j<<8;
  44. // lookup element index
  45. for(i=0,t[u]=j;t[i]-j;i++);
  46. u+=i==u;
  47. // parse amount
  48. for(n=0;*s>>4==3;)n=n*10+*s++-48;
  49. n+=!n;
  50. // store element count in molecule vector, flip sign for other side of '->'
  51. v[c][i]=r?n:-n;
  52. }
  53. // solve
  54. b(c);
  55. // output
  56. for(i=0,s=n?"Nope!":a[1];*s;putchar(*s++))s==m[i]&&t[i++]>1?printf("%d",t[i-1]):0;
  57. putchar(10);
  58. }
  59.  
  60. ./a.out "C7H16+O2->CO2+H2O"
  61. ./a.out "Al+Fe2O4->Fe+Al2O3"
  62. ./a.out "Pb->Au"
  63.  
  64. C7H16+11O2->7CO2+8H2O
  65. 8Al+3Fe2O4->6Fe+4Al2O3
  66. Nope!
  67.  
  68. b@t_ :=Quiet@Check[Module[{s = StringSplit[t, "+" | "->"], g = StringCases, k = Length,
  69. e, v, f, z, r},
  70. e = Union@Flatten[g[#, _?UpperCaseQ ~~ ___?LowerCaseQ] & /@ s];v = k@e;
  71. s_~f~e_ := If[g[s, e] == {}, 0, If[(r = g[s, e ~~ p__?DigitQ :> p]) == {}, 1,
  72. r /. {{x_} :> ToExpression@x}]];z = k@s - v;
  73. r = #/(GCD @@ #) &[Inverse[Join[SparseArray[{{i_, j_} :> f[s[[j]], e[[i]]]}, k /@ {e, s}],
  74. Table[Join[ConstantArray[0, {z, v}][[i]], #[[i]]], {i, k[#]}]]][[All, -1]] &
  75. [IdentityMatrix@z]];
  76. Row@Flatten[ReplacePart[Riffle[Partition[Riffle[Abs@r, s], 2], " + "],
  77. 2 Count[r, _?Negative] -> " -> "]]], "Nope!"]
  78.  
  79. b["C7H16+O2->CO2+H2O"]
  80. b["Al+Fe2O3->Fe+Al2O3"]
  81. b["Pb->Au"]
  82.  
  83. import sys,re
  84. from sympy.solvers import solve
  85. from sympy import Symbol
  86. from fractions import gcd
  87. from collections import defaultdict
  88.  
  89. Ls=list('abcdefghijklmnopqrstuvwxyz')
  90. eq=sys.argv[1]
  91. Ss,Os,Es,a,i=defaultdict(list),Ls[:],[],1,1
  92. for p in eq.split('->'):
  93. for k in p.split('+'):
  94. c = [Ls.pop(0), 1]
  95. for e,m in re.findall('([A-Z][a-z]?)([0-9]*)',k):
  96. m=1 if m=='' else int(m)
  97. a*=m
  98. d=[c[0],c[1]*m*i]
  99. Ss[e][:0],Es[:0]=[d],[[e,d]]
  100. i=-1
  101. Ys=dict((s,eval('Symbol("'+s+'")')) for s in Os if s not in Ls)
  102. Qs=[eval('+'.join('%d*%s'%(c[1],c[0]) for c in Ss[s]),{},Ys) for s in Ss]+[Ys['a']-a]
  103. k=solve(Qs,*Ys)
  104. if k:
  105. N=[k[Ys[s]] for s in sorted(Ys)]
  106. g=N[0]
  107. for a1, a2 in zip(N[0::2],N[1::2]):g=gcd(g,a2)
  108. N=[i/g for i in N]
  109. pM=lambda c: str(c) if c!=1 else ''
  110. print '->'.join('+'.join(pM(N.pop(0))+str(t) for t in p.split('+')) for p in eq.split('->'))
  111. else:print 'Nope!'
  112.  
  113. python chem-min.py "C7H16+O2->CO2+H2O"
  114. python chem-min.py "Al+Fe2O4->Fe+Al2O3"
  115. python chem-min.py "Pb->Au"
  116.  
  117. C7H16+11O2->7CO2+8H2O
  118. 8Al+3Fe2O4->6Fe+4Al2O3
  119. Nope!
  120.  
  121. from sympy import*
  122. import sys,re
  123. from sympy.solvers import*
  124. from collections import*
  125. P=str.split
  126. L=map(chr,range(97,123))
  127. q=sys.argv[1]
  128. S,O,a,i,u,v=defaultdict(list),L[:],1,1,'+','->'
  129. w=u.join
  130. for p in P(q,v):
  131. for k in P(p,u):
  132. c=L.pop(0)
  133. for e,m in re.findall('([A-Z][a-z]*)(d*)',k):
  134. m=int(m or 1)
  135. a*=m
  136. S[e][:0]=[c,m*i],
  137. i=-1
  138. Y=dict((s,Symbol(s))for s in set(O)-set(L))
  139. Q=[eval(w('%d*%s'%(c[1],c[0])for c in S[s]),{},Y)for s in S]+[Y['a']-a]
  140. k=solve(Q,*Y)
  141. if k:
  142. N=[k[Y[s]]for s in sorted(Y)]
  143. g=gcd(N[:1]+N[1::2])
  144. print v.join(w((lambda c:str(c)*(c!=1))(N.pop(0)/g)+str(t)for t in P(p,u))for p in P(q,v))
  145. else:print'Nope!'
Add Comment
Please, Sign In to add comment