สมดุลสมการทางเคมี!


30

Bernd เป็นนักเรียนมัธยมปลายที่มีปัญหาทางเคมี ในชั้นเรียนเขาต้องออกแบบสมการทางเคมีสำหรับการทดลองบางอย่างที่พวกเขาทำเช่นการเผาไหม้ของ heptane:

C 7 H 16 + 11O 2 → 7CO 2 + 8H 2 O

เนื่องจากคณิตศาสตร์ไม่ใช่วิชาที่แข็งแกร่งที่สุดของ Bernd เขามักจะมีช่วงเวลาที่ยากลำบากในการหาอัตราส่วนที่แน่นอนระหว่างกระบวนการและปฏิกิริยาของปฏิกิริยา เนื่องจากคุณเป็นติวเตอร์ของ Bernd มันเป็นหน้าที่ของคุณที่จะช่วยเขา! เขียนโปรแกรมที่คำนวณปริมาณของสารแต่ละชนิดที่จำเป็นเพื่อให้ได้สมการทางเคมีที่ถูกต้อง

อินพุต

อินพุตเป็นสมการทางเคมีโดยไม่มีปริมาณ เพื่อให้เป็นไปได้ใน ASCII บริสุทธิ์เราเขียนการสมัครสมาชิกใด ๆ เป็นหมายเลขสามัญ ชื่อองค์ประกอบเริ่มต้นด้วยอักษรตัวใหญ่เสมอและอาจตามด้วยจิ๋ว โมเลกุลจะถูกคั่นด้วย+เครื่องหมายลูกศร ASCII-art ->ถูกแทรกระหว่างทั้งสองด้านของสมการ:

Al+Fe2O4->Fe+Al2O3

อินพุตถูกยกเลิกด้วยการขึ้นบรรทัดใหม่และจะไม่มีช่องว่างใด ๆ หากอินพุตไม่ถูกต้องโปรแกรมของคุณอาจทำสิ่งที่คุณต้องการ

คุณอาจคิดว่าอินพุตไม่เกิน 1024 อักขระ โปรแกรมของคุณอาจอ่านอินพุตจากอินพุตมาตรฐานจากอาร์กิวเมนต์แรกหรือในวิธีการนำไปปฏิบัติที่กำหนด ณ รันไทม์หากไม่สามารถทำได้

เอาท์พุต

ผลลัพธ์ของโปรแกรมของคุณคือสมการอินพุตเพิ่มขึ้นด้วยตัวเลขพิเศษ จำนวนอะตอมสำหรับแต่ละองค์ประกอบจะต้องเท่ากันทั้งสองด้านของลูกศร สำหรับตัวอย่างข้างต้นผลลัพธ์ที่ถูกต้องคือ:

2Al+Fe2O3->2Fe+Al2O3

ถ้าจำนวนโมเลกุลเท่ากับ 1 ให้ลดลง ตัวเลขต้องเป็นจำนวนเต็มบวกเสมอ โปรแกรมของคุณจะต้องมีตัวเลขเพื่อให้ผลรวมของพวกเขาน้อยที่สุด ตัวอย่างเช่นสิ่งต่อไปนี้ผิดกฎหมาย:

40Al+20Fe2O3->40Fe+20Al2O3

หากไม่มีวิธีแก้ไขให้พิมพ์

Nope!

แทน. อินพุตตัวอย่างที่ไม่มีวิธีแก้ไขคือ

Pb->Au

กฎระเบียบ

  • นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุดชนะ
  • โปรแกรมของคุณจะต้องสิ้นสุดในเวลาที่เหมาะสมสำหรับอินพุตที่เหมาะสมทั้งหมด

กรณีทดสอบ

แต่ละกรณีทดสอบมีสองบรรทัด: อินพุตและเอาต์พุตที่ถูกต้อง

C7H16+O2->CO2+H2O
C7H16+11O2->7CO2+8H2O

Al+Fe2O3->Fe+Al2O3
2Al+Fe2O3->2Fe+Al2O3

Pb->Au
Nope!

1
ฉันอาจจะผิด แต่ดูเหมือนว่าผู้สมัครทั่วไปสำหรับความท้าทายในการเขียนโปรแกรมมากกว่าการเขียนโค้ดกอล์ฟ
DavidC

1
ฉันเคยเขียนแก้สมการทางเคมีในเครื่องคิดเลขกราฟ TI-89 ของฉันโดยใช้solve(ฟังก์ชั่นในตัวและeval(ตีความอินพุต :)
mellamokb

3
@mellamokb ทำไมคุณไม่โพสต์คุณจะได้รับ upvote จากฉันสำหรับความคิดริเริ่ม
ratchet freak

5
"เนื่องจากคุณเป็นครูสอนวิชา Bernds มันเป็นหน้าที่ของคุณที่จะช่วยเขา!" - ฉันคิดว่าติวเตอร์ควรสอนเบิร์นให้คิดด้วยตัวเองแทนที่จะเขียนซอฟต์แวร์ให้เขาเพื่อเขาจะได้ไม่ต้อง: P
naught101

1
@ KuilinLi มันไม่ผิดต่างไป
FUZxxl

คำตอบ:


7

C, 442 505ตัวอักษร

// element use table, then once parsed reused as molecule weights
u,t[99];

// molecules
char*s,*m[99]; // name and following separator
c,v[99][99]; // count-1, element vector

i,j,n;

// brute force solver, n==0 upon solution - assume at most 30 of each molecule
b(k){
    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
    else for(t[k]=0;n&&t[k]++<30;)b(k-1); // loop through all combos of weights
}

main(int r,char**a){
    // parse
    for(s=m[0]=a[1];*s;){
        // parse separator, advance next molecule
        if(*s==45)r=0,s++;
        if(*s<65)m[++c]=++s;
        // parse element
        j=*s++;
        if(*s>96)j=*s+++j<<8;            
        // lookup element index
        for(i=0,t[u]=j;t[i]-j;i++);
        u+=i==u;
        // parse amount
        for(n=0;*s>>4==3;)n=n*10+*s++-48;
        n+=!n;
        // store element count in molecule vector, flip sign for other side of '->'
        v[c][i]=r?n:-n;
    }
    // solve
    b(c);
    // output
    for(i=0,s=n?"Nope!":a[1];*s;putchar(*s++))s==m[i]&&t[i++]>1?printf("%d",t[i-1]):0;
    putchar(10);
}

ทำงานเป็น:

./a.out "C7H16+O2->CO2+H2O"
./a.out "Al+Fe2O4->Fe+Al2O3"
./a.out "Pb->Au"

ผล:

C7H16+11O2->7CO2+8H2O
8Al+3Fe2O4->6Fe+4Al2O3
Nope!

+1 สิ่งนี้เป็นที่น่านับถือมากกว่า Pres อภิปราย
ardnew

2
ลองใช้เครื่องหมายจุลภาคเป็นตัวคั่นคำสั่งเพื่อหลีกเลี่ยงวงเล็บปีกกา ลองเปลี่ยน if-then-else-constructs ด้วยโอเปอร์เรเตอร์ ternary เพื่อย่อรหัส t [ผม]> 1 printf ( "% s", t [ผม]): 0;? สั้นลงหนึ่งไบต์ นอกจากนี้: m [0] ก็เหมือนกับ * m
FUZxxl

6

Mathematica 507

ฉันใช้วิธีเมทริกซ์องค์ประกอบเคมีเพิ่มเติมที่อธิบายไว้ใน

LRThorne แนวทางใหม่ในการสร้างสมดุลของสมการปฏิกิริยาเคมี: เมทริกซ์ที่ง่ายขึ้น - เทคนิคผกผันสำหรับการหาพื้นที่ว่างของเมทริกซ์ Chem.Educator , 2010, 15, 304 - 308

เพิ่ม tweak เล็กน้อยหนึ่ง: ฉันแบ่งทรานสโพสของเวกเตอร์อวกาศว่างโดยตัวหารร่วมที่ยิ่งใหญ่ที่สุดขององค์ประกอบเพื่อให้แน่ใจว่าค่าจำนวนเต็มในการแก้ปัญหาใด ๆ การใช้งานของฉันยังไม่รองรับกรณีที่มีวิธีแก้ปัญหามากกว่าหนึ่งวิธีเพื่อสร้างสมดุลของสมการ

b@t_ :=Quiet@Check[Module[{s = StringSplit[t, "+" | "->"], g = StringCases, k = Length, 
  e, v, f, z, r},
e = Union@Flatten[g[#, _?UpperCaseQ ~~ ___?LowerCaseQ] & /@ s];v = k@e;
s_~f~e_ := If[g[s, e] == {}, 0, If[(r = g[s, e ~~ p__?DigitQ :> p]) == {}, 1, 
   r /. {{x_} :> ToExpression@x}]];z = k@s - v;
r = #/(GCD @@ #) &[Inverse[Join[SparseArray[{{i_, j_} :> f[s[[j]], e[[i]]]}, k /@ {e, s}], 
Table[Join[ConstantArray[0, {z, v}][[i]], #[[i]]], {i, k[#]}]]][[All, -1]] &
   [IdentityMatrix@z]];
Row@Flatten[ReplacePart[Riffle[Partition[Riffle[Abs@r, s], 2], " + "], 
   2 Count[r, _?Negative] -> " -> "]]], "Nope!"]

การทดสอบ

b["C7H16+O2->CO2+H2O"]
b["Al+Fe2O3->Fe+Al2O3"]
b["Pb->Au"]

ป้อนคำอธิบายรูปภาพที่นี่

การวิเคราะห์

มันทำงานได้โดยการตั้งค่าตารางองค์ประกอบทางเคมีต่อไปนี้ซึ่งประกอบด้วยชนิดของสารเคมีตามองค์ประกอบซึ่งมีการเพิ่มเวกเตอร์ค่าความว่างเปล่าเพิ่มเติม (กลายเป็นตารางองค์ประกอบทางเคมีที่เพิ่มขึ้น:

ตารางองค์ประกอบทางเคมี

เซลล์ด้านในจะถูกลบออกเป็นเมทริกซ์และคว่ำให้ผล

การผกผัน

คอลัมน์ขวาสุดถูกดึงออกมาแล้วให้ผลดังนี้

{- (1/8), - (11/8), 7/8, 1}

แต่ละองค์ประกอบในเวกเตอร์จะถูกหารด้วย gcd ขององค์ประกอบ (1/8) โดยให้:

{-1, -11, 7, 8}

โดยที่ค่าลบจะถูกวางไว้ที่ด้านซ้ายของลูกศร ค่าสัมบูรณ์ของค่าเหล่านี้คือตัวเลขที่จำเป็นในการสร้างสมดุลของสมการดั้งเดิม:

วิธีการแก้


อย่าลืมเพิ่มเครื่องหมายอัศเจรีย์!
ardnew

:} ตกลงและฉันเพิ่มจำนวนตัวละครขึ้นไป
DavidC

ฉันคิดว่าคุณหมายถึงคอลัมน์ทางขวาไม่ใช่คอลัมน์ทางซ้าย ฉันขอขอบคุณคำอธิบาย (+1) แต่ฉันสงสัยว่า: หากไม่ใช่กรณีที่จำนวนโมเลกุลมากกว่าจำนวนขององค์ประกอบคุณจะรองได้อย่างไร ปิดเพื่ออ่านกระดาษทันที
Peter Taylor

ด้วยเหตุผลบางอย่างฉันเพิ่งเจอความคิดเห็นของคุณในวันนี้ ใช่ฉันหมายถึง "คอลัมน์ด้านขวา" เวลาผ่านไปนานมากแล้วตั้งแต่ฉันทำงานในเรื่องนี้ซึ่งฉันไม่สามารถมองเห็น (หรือจำได้) ที่ใช้ในการขยาย ขอโทษ
DavidC

3

Python 880 ตัวอักษร

import sys,re
from sympy.solvers import solve
from sympy import Symbol
from fractions import gcd
from collections import defaultdict

Ls=list('abcdefghijklmnopqrstuvwxyz')
eq=sys.argv[1]
Ss,Os,Es,a,i=defaultdict(list),Ls[:],[],1,1
for p in eq.split('->'):
 for k in p.split('+'):
  c = [Ls.pop(0), 1]
  for e,m in re.findall('([A-Z][a-z]?)([0-9]*)',k):
   m=1 if m=='' else int(m)
   a*=m
   d=[c[0],c[1]*m*i]
   Ss[e][:0],Es[:0]=[d],[[e,d]]
 i=-1
Ys=dict((s,eval('Symbol("'+s+'")')) for s in Os if s not in Ls)
Qs=[eval('+'.join('%d*%s'%(c[1],c[0]) for c in Ss[s]),{},Ys) for s in Ss]+[Ys['a']-a]
k=solve(Qs,*Ys)
if k:
 N=[k[Ys[s]] for s in sorted(Ys)]
 g=N[0]
 for a1, a2 in zip(N[0::2],N[1::2]):g=gcd(g,a2)
 N=[i/g for i in N]
 pM=lambda c: str(c) if c!=1 else ''
 print '->'.join('+'.join(pM(N.pop(0))+str(t) for t in p.split('+')) for p in eq.split('->'))
else:print 'Nope!'

แบบทดสอบ:

python chem-min.py "C7H16+O2->CO2+H2O"
python chem-min.py "Al+Fe2O4->Fe+Al2O3"
python chem-min.py "Pb->Au"

เอาท์พุท:

C7H16+11O2->7CO2+8H2O
8Al+3Fe2O4->6Fe+4Al2O3
Nope!

อาจน้อยกว่า 880 แต่ดวงตาของฉันกำลังฆ่าฉันอยู่แล้ว ...


2

Python 2, 635 ไบต์

จำนวนไบต์ก่อนหน้า: 794, 776, 774, 765, 759, 747, 735, 734, 720, 683, 658, 655, 654, 653, 651, 638, 637, 636 ไบต์

ระดับการเยื้องที่สองเป็นเพียงแท็บส่วนที่สามคือแท็บตามด้วยช่องว่าง

พูดตามตรงนี่คือคำตอบของ jadkik94 แต่มีหลายไบต์ที่ถูกโกนผมต้องทำมัน บอกฉันว่าฉันสามารถโกนไบต์ใด ๆ ได้ไหม!

from sympy import*
import sys,re
from sympy.solvers import*
from collections import*
P=str.split
L=map(chr,range(97,123))
q=sys.argv[1]
S,O,a,i,u,v=defaultdict(list),L[:],1,1,'+','->'
w=u.join
for p in P(q,v):
 for k in P(p,u):
     c=L.pop(0)
     for e,m in re.findall('([A-Z][a-z]*)(\d*)',k):
      m=int(m or 1)
      a*=m
      S[e][:0]=[c,m*i],
 i=-1
Y=dict((s,Symbol(s))for s in set(O)-set(L))
Q=[eval(w('%d*%s'%(c[1],c[0])for c in S[s]),{},Y)for s in S]+[Y['a']-a]
k=solve(Q,*Y)
if k:
 N=[k[Y[s]]for s in sorted(Y)]
 g=gcd(N[:1]+N[1::2])
 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))
else:print'Nope!'

บันทึกสามไบต์:: ''.join(map(chr,range(97,122)))D
aliqandil

:( นั่นไม่ได้ผลอย่างไรก็ตามmap(chr,range(97,123))ใช้ได้กับการบันทึก 12 ไบต์
Zacharý

โอ้ใช่! มันคือหลาม 2!
aliqandil

1

JavaScript, 682 ไบต์

x=>{m=1;x.split(/\D+/g).map(i=>i?m*=i:0);e=new Set(x.replace(/\d+|\+|->/g,"").match(/([A-Z][a-z]*)/g));e.delete``;A=[];for(let z of e){t=x.split`->`;u=[];for(c=1;Q=t.shift();c=-1)Q.split`+`.map(p=>u.push(c*((i=p.indexOf(z))==-1?0:(N=p.substring(i+z.length).match(/^\d+/g))?N[0]:1)));A.push(u)}J=A.length;for(P=0;P<J;P++){for(i=P;!A[i][P];i++);W=A.splice(i,1)[0];W=W.map(t=>t*m/W[P]);A=A.map(r=>r[P]?r.map((t,j)=>t-W[j]*r[P]/m):r);A.splice(P,0,W)}f=e.size;if(!A[0][f])return"Nope!";g=m=-m;_=(a,b)=>b?_(b,a%b):a;c=[];A.map(p=>c.push(t=p.pop())&(g=_(g,t)));c.push(m);j=x.match(/[^+>]+/g);return c.map(k=>k/g).map(t=>(t^1?t:"")+(z=j.shift())+(z.endsWith`-`?">":"+")).join``.slice(0,-1);}

นี่เป็นคำตอบของ Kuilin ที่ตีกอล์ฟมากขึ้น (ตัวละครหลายสิบตัว!) อาจไม่ใช่การคอมไพล์เนื่องจากคุณลักษณะบางอย่างของ JS โพสต์ลงวันที่ท้าทาย


0

Javascript, 705 ไบต์

(ไม่ใช่การแข่งขันคุณสมบัติบางอย่างโพสต์วันที่ท้าทาย)

โซลูชันอื่น ๆ ทั้งหมดมีองค์ประกอบของการเดรัจฉานบังคับ ฉันพยายามหาวิธีกำหนดรูปแบบมากขึ้นโดยการแสดงสมการทางเคมีเป็นชุดของสมการเชิงเส้นแล้วแก้โดยใช้อัลกอริทึม Gauss-Jordan เพื่อลดรูปแบบแถวแถวของเมทริกนั้น เพื่อที่จะแยกกรณีเล็ก ๆ น้อย ๆ ที่ทุกอย่างเป็นศูนย์ฉันคิดว่าหนึ่งในองค์ประกอบนั้นเป็นจำนวนคงที่ - และจำนวนนั้นจะถูกกำหนดโดยตัวเลขทั้งหมดที่คูณด้วยกันเพื่อไม่ให้มีเศษส่วน จากนั้นเป็นขั้นตอนสุดท้ายเราจะแบ่ง gcd แต่ละอันเพื่อให้เป็นไปตามเงื่อนไขสุดท้าย

Ungolfed:

function solve(x) {
	//firstly we find bigNumber, which will be all numbers multiplied together, in order to assume the last element is a constant amount of that
	bigNumber = 1;
	arrayOfNumbers = new Set(x.split(/\D+/g));
	arrayOfNumbers.delete("");
	for (let i of arrayOfNumbers) bigNumber *= parseInt(i);
	
	//first actual step, we split into left hand side and right hand side, and then into separate molecules
	//number of molecules is number of variables, number of elements is number of equations, variables refer to the coefficients of the chemical equation
	//note, the structure of this is changed a lot in the golfed version since right is the same as negative left
	left = x.split("->")[0].split("+");
	righ = x.split("->")[1].split("+");
	molecules = left.length + righ.length;
	
	//then let's find what elements there are - this will also become how many equations we have, or the columns of our matrix minus one
	//we replace all the non-element characters, and then split based on the uppercase characters
	//this also sometimes adds a "" to the array, we don't need that so we just delete it
	//turn into a set in order to remove repeats
	elems = new Set(x.replace(/\d+|\+|->/g,"").match(/([A-Z][a-z]*)/g));
	elems.delete("");
	
	rrefArray = [];//first index is rows, second index columns - each row is an equation x*(A11)+y*(A21)+z*(A31)=A41 etc etc, to solve for xyz as coefficients
	//loop thru the elements, since for each element we'll have an equation, or a row in the array
	for (let elem of elems) {
		buildArr = [];
		//loop thru the sides
		for (let molecule of left) {
			//let's see how many of element elem are in molecule molecule
			//ASSUMPTION: each element happens only once per molecule (no shenanigans like CH3COOH)
			index = molecule.indexOf(elem);
			if (index == -1) buildArr.push(0);
			else {
				index += elem.length;
				numberAfterElement = molecule.substring(index).match(/^\d+/g);
				if (numberAfterElement == null) buildArr.push(1);
				else buildArr.push(parseInt(numberAfterElement));
			}
		}
		//same for right, except each item is negative
		for (let molecule of righ) {
			index = molecule.indexOf(elem);
			if (index == -1) buildArr.push(0);
			else {
				index += elem.length;
				numberAfterElement = molecule.substring(index).match(/^\d+/g);
				if (numberAfterElement == null) buildArr.push(-1);
				else buildArr.push(parseInt(numberAfterElement)*(-1));
			}
		}
		rrefArray.push(buildArr);
	}
	
	//Gauss-Jordan algorithm starts here, on rrefArray
	for (pivot=0;pivot<Math.min(molecules, elems.size);pivot++) {
		//for each pivot element, first we search for a row in which the pivot is nonzero
		//this is guaranteed to exist because there are no empty molecules
		for (i=pivot;i<rrefArray.length;i++) {
			row = rrefArray[i];
			if (row[pivot] != 0) {
				workingOnThisRow = rrefArray.splice(rrefArray.indexOf(row), 1)[0];
			}
		}
		//then multiply elements so the pivot element of workingOnThisRow is equal to bigNumber we determined above, this is all to keep everything in integer-space
		multiplyWhat = bigNumber / workingOnThisRow[pivot]
		for (i=0;i<workingOnThisRow.length;i++) workingOnThisRow[i] *= multiplyWhat
		//then we make sure the other rows don't have this column as a number, the other rows have to be zero, if not we can normalize to bigNumber and subtract
		for (let i in rrefArray) {
			row = rrefArray[i];
			if (row[pivot] != 0) {
				multiplyWhat = bigNumber / row[pivot]
				for (j=0;j<row.length;j++) {
					row[j] *= multiplyWhat;
					row[j] -= workingOnThisRow[j];
					row[j] /= multiplyWhat;
				}
				rrefArray[i]=row;
			}
		}
		//finally we put the row back
		rrefArray.splice(pivot, 0, workingOnThisRow);
	}
	
	//and finally we're done!
	//sanity check to make sure it succeeded, if not then the matrix is insolvable
	if (rrefArray[0][elems.size] == 0 || rrefArray[0][elems.size] == undefined) return "Nope!";
	
	//last step - get the results of the rref, which will be the coefficients of em except for the last one, which would be bigNumber (1 with typical implementation of the algorithm)
	bigNumber *= -1;
	gcd_calc = function(a, b) {
		if (!b) return a;
		return gcd_calc(b, a%b);
	};
	coEffs = [];
	gcd = bigNumber;
	for (i=0;i<rrefArray.length;i++) {
		num = rrefArray[i][molecules-1];
		coEffs.push(num);
		gcd = gcd_calc(gcd, num)
	}
	coEffs.push(bigNumber);
	for (i=0;i<coEffs.length;i++) coEffs[i] /= gcd;
	
	//now we make it human readable
	//we have left and right from before, let's not forget those!
	out = "";
	for (i=0;i<coEffs.length;i++) {
		coEff = coEffs[i];
		if (coEff != 1) out += coEff;
		out += left.shift();
		if (left.length == 0 && righ.length != 0) {
			out += "->";
			left = righ;
		} else if (i != coEffs.length-1) out += "+";
	}
	return out;
}
console.log(solve("Al+Fe2O4->Fe+Al2O3"));
console.log(solve("Al+Fe2O3->Fe+Al2O3"));
console.log(solve("C7H16+O2->CO2+H2O"));
console.log(solve("Pb->Au"));

แข็งแรงเล่นกอล์ฟ

s=x=>{m=1;x.split(/\D+/g).map(i=>i!=""?m*=i:0);e=(new Set(x.replace(/\d+|\+|->/g,"").match(/([A-Z][a-z]*)/g)));e.delete("");A=[];for(let z of e){t=x.split("->");u=[];for(c=1;Q=t.shift();c=-1)Q.split("+").map(p=>u.push(c*((i=p.indexOf(z))==-1?0:(N=p.substring(i+z.length).match(/^\d+/g))?N[0]:1)));A.push(u)}J=A.length;for(P=0;P<J;P++){for(i=P;!A[i][P];i++);W=A.splice(i,1)[0];W=W.map(t=>t*m/W[P]);A=A.map(r=>!r[P]?r:r.map((t,j)=>t-W[j]*r[P]/m));A.splice(P,0,W)}f=e.size;if (!A[0][f])return "Nope!";g=m=-m;_=(a,b)=>b?_(b,a%b):a;c=[];A.map(p=>c.push(t=p.pop())&(g=_(g,t)));c.push(m);j=x.match(/[^+>]+/g);return c.map(k=>k/g).map(t=>(t==1?"":t)+(z=j.shift())+(z.endsWith("-")?">":"+")).join("").slice(0,-1);}

console.log(s("Al+Fe2O4->Fe+Al2O3"));
console.log(s("Al+Fe2O3->Fe+Al2O3"));
console.log(s("C7H16+O2->CO2+H2O"));
console.log(s("Pb->Au"));


1
ไม่ใช่การแข่งขันเนื่องจากคุณสมบัติบางอย่างจะโพสต์ความท้าทาย
Zacharý

โอ้ว้าวฉันไม่ได้สังเกตว่าอายุเท่านี้ ขอบคุณ!
Kuilin Li
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.