Chemical calculator: Difference between revisions
Content added Content deleted
MaiconSoft (talk | contribs) No edit summary |
|||
Line 992: | Line 992: | ||
C27H46O -> 386.664 |
C27H46O -> 386.664 |
||
Uue -> 315.000</pre> |
Uue -> 315.000</pre> |
||
=={{header|Delphi}}== |
|||
{{trans|Go}} |
|||
<lang Delphi> |
|||
program ChemicalCalculator; |
|||
{$APPTYPE CONSOLE} |
|||
{$R *.res} |
|||
uses |
|||
System.SysUtils, |
|||
System.Generics.Collections; |
|||
{$I AtomicMass.inc } |
|||
type |
|||
TAtomicMass = class(TDictionary<string, Double>) |
|||
public |
|||
constructor Create(Keys: array of string; Values: array of Double); overload; |
|||
end; |
|||
{ TAtomicMass } |
|||
constructor TAtomicMass.Create(Keys: array of string; Values: array of Double); |
|||
var |
|||
i: Integer; |
|||
begin |
|||
inherited Create; |
|||
Assert(length(Keys) = Length(Values), 'Keys and values must have the same size'); |
|||
if Length(Keys) = 0 then |
|||
exit; |
|||
for i := 0 to High(Keys) do |
|||
Add(Keys[i], Values[i]); |
|||
end; |
|||
var |
|||
AtomicMassData: TAtomicMass; |
|||
function Evaluate(s: string): Double; |
|||
var |
|||
sum: Double; |
|||
symbol: string; |
|||
number: string; |
|||
c: char; |
|||
i, n: Integer; |
|||
begin |
|||
s := s + '['; |
|||
symbol := ''; |
|||
number := ''; |
|||
for i := 1 to s.Length do |
|||
begin |
|||
c := s[i]; |
|||
if ('@' <= c) and (c <= '[') then |
|||
begin |
|||
n := 1; |
|||
if not number.IsEmpty then |
|||
n := StrToInt(number); |
|||
if not symbol.IsEmpty then |
|||
sum := sum + AtomicMassData[symbol] * n; |
|||
if c = '[' then |
|||
Break; |
|||
symbol := c; |
|||
number := ''; |
|||
Continue; |
|||
end; |
|||
if ('a' <= c) and (c <= 'z') then |
|||
begin |
|||
symbol := symbol + c; |
|||
Continue; |
|||
end; |
|||
if ('0' <= c) and (c <= '9') then |
|||
begin |
|||
number := number + c; |
|||
Continue; |
|||
end; |
|||
raise Exception.Create('Unexpected symbol ' + c + ' in molecule'); |
|||
end; |
|||
Result := sum; |
|||
end; |
|||
function ReplaceFirst(text, search, replace: string): string; |
|||
var |
|||
pos: Integer; |
|||
begin |
|||
pos := text.IndexOf(search); |
|||
if (pos < 0) then |
|||
Exit(text); |
|||
Result := text.Substring(0, pos) + replace + text.Substring(pos + search.Length); |
|||
end; |
|||
function ReplaceParens(s: string): string; |
|||
var |
|||
letter: Char; |
|||
start: Integer; |
|||
i: Integer; |
|||
expr, symbol: string; |
|||
begin |
|||
letter := 's'; |
|||
while True do |
|||
begin |
|||
start := s.IndexOf('('); |
|||
if (start = -1) then |
|||
Break; |
|||
for i := start + 1 to s.Length - 1 do |
|||
begin |
|||
if s[i + 1] = ')' then |
|||
begin |
|||
expr := s.Substring(start + 1, i - start - 1); |
|||
symbol := '@' + letter; |
|||
s := ReplaceFirst(s, s.Substring(start, i + 1 - start), symbol); |
|||
if not (AtomicMassData.ContainsKey(symbol)) then |
|||
AtomicMassData.Add(symbol, Evaluate(expr)) |
|||
else |
|||
AtomicMassData[symbol] := Evaluate(expr); |
|||
inc(letter); |
|||
Break; |
|||
end; |
|||
if (s[i + 1] = '(') then |
|||
start := i; |
|||
end; |
|||
end; |
|||
Result := s; |
|||
end; |
|||
var |
|||
molecules: array of string; |
|||
i: Integer; |
|||
mass: Double; |
|||
begin |
|||
molecules := ['H', 'H2', 'H2O', 'H2O2', '(HO)2', 'Na2SO4', 'C6H12', |
|||
'COOH(C(CH3)2)3CH3', 'C6H4O2(OH)4', 'C27H46O', 'Uue']; |
|||
AtomicMassData := TAtomicMass.Create(ATOMIC_MASS_SYMBOL, ATOMIC_MASS_VALUE); |
|||
for i := 0 to 10 do |
|||
begin |
|||
mass := Evaluate(ReplaceParens(molecules[i])); |
|||
Writeln(format('%17s -> %7s', [molecules[i], FormatFloat('####.000',mass)])); |
|||
end; |
|||
AtomicMassData.Free; |
|||
readln; |
|||
end. |
|||
</lang> |
|||
Include file with Atomic Mass Constants ('''AtomicMass.inc'''). |
|||
<lang Delphi> |
|||
const |
|||
ATOMIC_MASS_SIZE = 101; |
|||
ATOMIC_MASS_SYMBOL: array[0..ATOMIC_MASS_SIZE - 1] of string = ('H', 'He', |
|||
'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', |
|||
'Cl', 'Ar', 'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', |
|||
'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', |
|||
'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I', 'Xe', 'Cs', 'Ba', |
|||
'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', |
|||
'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', |
|||
'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', |
|||
'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Uue', 'Ubn'); |
|||
ATOMIC_MASS_VALUE: array[0..ATOMIC_MASS_SIZE - 1] of double = (1.008, 4.002602, |
|||
6.94, 9.0121831, 10.81, 12.011, 14.007, 15.999, 18.998403163, 20.1797, |
|||
22.98976928, 24.305, 26.9815385, 28.085, 30.973761998, 32.06, 35.45, 39.948, |
|||
39.0983, 40.078, 44.955908, 47.867, 50.9415, 51.9961, 54.938044, 55.845, |
|||
58.933194, 58.6934, 63.546, 65.38, 69.723, 72.630, 74.921595, 78.971, 79.904, |
|||
83.798, 85.4678, 87.62, 88.90584, 91.224, 92.90637, 95.95, 101.07, 102.90550, |
|||
106.42, 107.8682, 112.414, 114.818, 118.710, 121.760, 127.60, 126.90447, |
|||
131.293, 132.90545196, 137.327, 138.90547, 140.116, 140.90766, 144.242, 145, |
|||
150.36, 151.964, 157.25, 158.92535, 162.500, 164.93033, 167.259, 168.93422, |
|||
173.054, 174.9668, 178.49, 180.94788, 183.84, 186.207, 190.23, 192.217, |
|||
195.084, 196.966569, 200.592, 204.38, 207.2, 208.98040, 209, 210, 222, 223, |
|||
226, 227, 232.0377, 231.03588, 238.02891, 237, 244, 243, 247, 247, 251, 252, |
|||
257, 315, 299); |
|||
</lang> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |