Chemical calculator: Difference between revisions
Content added Content deleted
MaiconSoft (talk | contribs) No edit summary |
|||
Line 315: | Line 315: | ||
UueCl : 350.450 |
UueCl : 350.450 |
||
</pre> |
</pre> |
||
=={{header|C}}== |
|||
<lang c>#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
typedef char *string; |
|||
typedef struct node_t { |
|||
string symbol; |
|||
double weight; |
|||
struct node_t *next; |
|||
} node; |
|||
node *make_node(string symbol, double weight) { |
|||
node *nptr = malloc(sizeof(node)); |
|||
if (nptr) { |
|||
nptr->symbol = symbol; |
|||
nptr->weight = weight; |
|||
nptr->next = NULL; |
|||
return nptr; |
|||
} |
|||
return NULL; |
|||
} |
|||
void free_node(node *ptr) { |
|||
if (ptr) { |
|||
free_node(ptr->next); |
|||
ptr->next = NULL; |
|||
free(ptr); |
|||
} |
|||
} |
|||
node *insert(string symbol, double weight, node *head) { |
|||
node *nptr = make_node(symbol, weight); |
|||
nptr->next = head; |
|||
return nptr; |
|||
} |
|||
node *dic; |
|||
void init() { |
|||
dic = make_node("H", 1.008); |
|||
dic = insert("He", 4.002602, dic); |
|||
dic = insert("Li", 6.94, dic); |
|||
dic = insert("Be", 9.0121831, dic); |
|||
dic = insert("B", 10.81, dic); |
|||
dic = insert("C", 12.011, dic); |
|||
dic = insert("N", 14.007, dic); |
|||
dic = insert("O", 15.999, dic); |
|||
dic = insert("F", 18.998403163, dic); |
|||
dic = insert("Ne", 20.1797, dic); |
|||
dic = insert("Na", 22.98976928, dic); |
|||
dic = insert("Mg", 24.305, dic); |
|||
dic = insert("Al", 26.9815385, dic); |
|||
dic = insert("Si", 28.085, dic); |
|||
dic = insert("P", 30.973761998, dic); |
|||
dic = insert("S", 32.06, dic); |
|||
dic = insert("Cl", 35.45, dic); |
|||
dic = insert("Ar", 39.948, dic); |
|||
dic = insert("K", 39.0983, dic); |
|||
dic = insert("Ca", 40.078, dic); |
|||
dic = insert("Sc", 44.955908, dic); |
|||
dic = insert("Ti", 47.867, dic); |
|||
dic = insert("V", 50.9415, dic); |
|||
dic = insert("Cr", 51.9961, dic); |
|||
dic = insert("Mn", 54.938044, dic); |
|||
dic = insert("Fe", 55.845, dic); |
|||
dic = insert("Co", 58.933194, dic); |
|||
dic = insert("Ni", 58.6934, dic); |
|||
dic = insert("Cu", 63.546, dic); |
|||
dic = insert("Zn", 65.38, dic); |
|||
dic = insert("Ga", 69.723, dic); |
|||
dic = insert("Ge", 72.630, dic); |
|||
dic = insert("As", 74.921595, dic); |
|||
dic = insert("Se", 78.971, dic); |
|||
dic = insert("Br", 79.904, dic); |
|||
dic = insert("Kr", 83.798, dic); |
|||
dic = insert("Rb", 85.4678, dic); |
|||
dic = insert("Sr", 87.62, dic); |
|||
dic = insert("Y", 88.90584, dic); |
|||
dic = insert("Zr", 91.224, dic); |
|||
dic = insert("Nb", 92.90637, dic); |
|||
dic = insert("Mo", 95.95, dic); |
|||
dic = insert("Ru", 101.07, dic); |
|||
dic = insert("Rh", 102.90550, dic); |
|||
dic = insert("Pd", 106.42, dic); |
|||
dic = insert("Ag", 107.8682, dic); |
|||
dic = insert("Cd", 112.414, dic); |
|||
dic = insert("In", 114.818, dic); |
|||
dic = insert("Sn", 118.710, dic); |
|||
dic = insert("Sb", 121.760, dic); |
|||
dic = insert("Te", 127.60, dic); |
|||
dic = insert("I", 126.90447, dic); |
|||
dic = insert("Xe", 131.293, dic); |
|||
dic = insert("Cs", 132.90545196, dic); |
|||
dic = insert("Ba", 137.327, dic); |
|||
dic = insert("La", 138.90547, dic); |
|||
dic = insert("Ce", 140.116, dic); |
|||
dic = insert("Pr", 140.90766, dic); |
|||
dic = insert("Nd", 144.242, dic); |
|||
dic = insert("Pm", 145, dic); |
|||
dic = insert("Sm", 150.36, dic); |
|||
dic = insert("Eu", 151.964, dic); |
|||
dic = insert("Gd", 157.25, dic); |
|||
dic = insert("Tb", 158.92535, dic); |
|||
dic = insert("Dy", 162.500, dic); |
|||
dic = insert("Ho", 164.93033, dic); |
|||
dic = insert("Er", 167.259, dic); |
|||
dic = insert("Tm", 168.93422, dic); |
|||
dic = insert("Yb", 173.054, dic); |
|||
dic = insert("Lu", 174.9668, dic); |
|||
dic = insert("Hf", 178.49, dic); |
|||
dic = insert("Ta", 180.94788, dic); |
|||
dic = insert("W", 183.84, dic); |
|||
dic = insert("Re", 186.207, dic); |
|||
dic = insert("Os", 190.23, dic); |
|||
dic = insert("Ir", 192.217, dic); |
|||
dic = insert("Pt", 195.084, dic); |
|||
dic = insert("Au", 196.966569, dic); |
|||
dic = insert("Hg", 200.592, dic); |
|||
dic = insert("Tl", 204.38, dic); |
|||
dic = insert("Pb", 207.2, dic); |
|||
dic = insert("Bi", 208.98040, dic); |
|||
dic = insert("Po", 209, dic); |
|||
dic = insert("At", 210, dic); |
|||
dic = insert("Rn", 222, dic); |
|||
dic = insert("Fr", 223, dic); |
|||
dic = insert("Ra", 226, dic); |
|||
dic = insert("Ac", 227, dic); |
|||
dic = insert("Th", 232.0377, dic); |
|||
dic = insert("Pa", 231.03588, dic); |
|||
dic = insert("U", 238.02891, dic); |
|||
dic = insert("Np", 237, dic); |
|||
dic = insert("Pu", 244, dic); |
|||
dic = insert("Am", 243, dic); |
|||
dic = insert("Cm", 247, dic); |
|||
dic = insert("Bk", 247, dic); |
|||
dic = insert("Cf", 251, dic); |
|||
dic = insert("Es", 252, dic); |
|||
dic = insert("Fm", 257, dic); |
|||
dic = insert("Uue", 315, dic); |
|||
dic = insert("Ubn", 299, dic); |
|||
} |
|||
double lookup(string symbol) { |
|||
for (node *ptr = dic; ptr; ptr = ptr->next) { |
|||
if (strcmp(symbol, ptr->symbol) == 0) { |
|||
return ptr->weight; |
|||
} |
|||
} |
|||
printf("symbol not found: %s\n", symbol); |
|||
return 0.0; |
|||
} |
|||
double total(double mass, int count) { |
|||
if (count > 0) { |
|||
return mass * count; |
|||
} |
|||
return mass; |
|||
} |
|||
double total_s(string sym, int count) { |
|||
double mass = lookup(sym); |
|||
return total(mass, count); |
|||
} |
|||
double evaluate_c(string expr, size_t *pos, double mass) { |
|||
int count = 0; |
|||
if (expr[*pos] < '0' || '9' < expr[*pos]) { |
|||
printf("expected to find a count, saw the character: %c\n", expr[*pos]); |
|||
} |
|||
for (; expr[*pos]; (*pos)++) { |
|||
char c = expr[*pos]; |
|||
if ('0' <= c && c <= '9') { |
|||
count = count * 10 + c - '0'; |
|||
} else { |
|||
break; |
|||
} |
|||
} |
|||
return total(mass, count); |
|||
} |
|||
double evaluate_p(string expr, size_t limit, size_t *pos) { |
|||
char sym[4]; |
|||
int sym_pos = 0; |
|||
int count = 0; |
|||
double sum = 0.0; |
|||
for (; *pos < limit && expr[*pos]; (*pos)++) { |
|||
char c = expr[*pos]; |
|||
if ('A' <= c && c <= 'Z') { |
|||
if (sym_pos > 0) { |
|||
sum += total_s(sym, count); |
|||
sym_pos = 0; |
|||
count = 0; |
|||
} |
|||
sym[sym_pos++] = c; |
|||
sym[sym_pos] = 0; |
|||
} else if ('a' <= c && c <= 'z') { |
|||
sym[sym_pos++] = c; |
|||
sym[sym_pos] = 0; |
|||
} else if ('0' <= c && c <= '9') { |
|||
count = count * 10 + c - '0'; |
|||
} else if (c == '(') { |
|||
if (sym_pos > 0) { |
|||
sum += total_s(sym, count); |
|||
sym_pos = 0; |
|||
count = 0; |
|||
} |
|||
(*pos)++; // skip past the paren |
|||
double mass = evaluate_p(expr, limit, pos); |
|||
sum += evaluate_c(expr, pos, mass); |
|||
(*pos)--; // neutralize the position increment |
|||
} else if (c == ')') { |
|||
if (sym_pos > 0) { |
|||
sum += total_s(sym, count); |
|||
sym_pos = 0; |
|||
count = 0; |
|||
} |
|||
(*pos)++; |
|||
return sum; |
|||
} else { |
|||
printf("Unexpected character encountered: %c\n", c); |
|||
} |
|||
} |
|||
if (sym_pos > 0) { |
|||
sum += total_s(sym, count); |
|||
} |
|||
return sum; |
|||
} |
|||
double evaluate(string expr) { |
|||
size_t limit = strlen(expr); |
|||
size_t pos = 0; |
|||
return evaluate_p(expr, limit, &pos); |
|||
} |
|||
void test(string expr) { |
|||
double mass = evaluate(expr); |
|||
printf("%17s -> %7.3f\n", expr, mass); |
|||
} |
|||
int main() { |
|||
init(); |
|||
test("H"); |
|||
test("H2"); |
|||
test("H2O"); |
|||
test("H2O2"); |
|||
test("(HO)2"); |
|||
test("Na2SO4"); |
|||
test("C6H12"); |
|||
test("COOH(C(CH3)2)3CH3"); |
|||
test("C6H4O2(OH)4"); |
|||
test("C27H46O"); |
|||
test("Uue"); |
|||
free_node(dic); |
|||
dic = NULL; |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> H -> 1.008 |
|||
H2 -> 2.016 |
|||
H2O -> 18.015 |
|||
H2O2 -> 34.014 |
|||
(HO)2 -> 34.014 |
|||
Na2SO4 -> 142.036 |
|||
C6H12 -> 84.162 |
|||
COOH(C(CH3)2)3CH3 -> 186.295 |
|||
C6H4O2(OH)4 -> 176.124 |
|||
C27H46O -> 386.664 |
|||
Uue -> 315.000</pre> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |