summaryrefslogtreecommitdiff
path: root/numbers-thing
diff options
context:
space:
mode:
Diffstat (limited to 'numbers-thing')
-rw-r--r--numbers-thing/numbers-thing.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/numbers-thing/numbers-thing.c b/numbers-thing/numbers-thing.c
new file mode 100644
index 0000000..e523828
--- /dev/null
+++ b/numbers-thing/numbers-thing.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+
+enum operator {
+ OP_MULTIPLY,
+ OP_DIVIDE,
+ OP_ADD,
+ OP_SUBTRACT,
+ OP_IDENTITY /* marks leaves */
+};
+
+struct bnode {
+ int value;
+ enum operator operator;
+ struct bnode *left;
+ struct bnode *right;
+};
+
+char
+op_lookup(enum operator op) {
+ switch (op) {
+ case OP_MULTIPLY: return '*';
+ case OP_DIVIDE: return '/';
+ case OP_ADD: return '+';
+ case OP_SUBTRACT: return '-';
+ default:
+ /* FIXME return this, error out somehow else? */
+ return '?';
+ }
+}
+
+double
+evaluate_op(double left, enum operator op, double right) {
+ switch(op) {
+ case OP_MULTIPLY: return left * right;
+ case OP_DIVIDE: return (double)left / right;
+ case OP_ADD: return left + right;
+ case OP_SUBTRACT: return left - right;
+ default:
+ /* FIXME return nan */
+ return -100000;
+ }
+}
+
+double
+evaluate(struct bnode* node) {
+ if (node->operator == OP_IDENTITY)
+ return node->value;
+
+ /* FIXME could/should NULL-check children
+ * Non-identity node should have two childre, but I might manage to
+ * screw it up somehow eh */
+ return evaluate_op(
+ evaluate(node->left),
+ node->operator,
+ evaluate(node->right));
+}
+
+void
+dump_tree(struct bnode *node) {
+ if (node->operator == OP_IDENTITY) {
+ printf("%d", node->value);
+ return;
+ }
+
+ printf("(");
+ if (node->left != NULL)
+ dump_tree(node->left);
+
+ printf(" %c ", op_lookup(node->operator));
+
+ if (node->right != NULL)
+ dump_tree(node->right);
+ printf(")");
+}
+
+int
+main(int argc, char **argv) {
+ struct bnode a,b,c,d,e, o1,o2,o3,o4;
+
+/* ((1+2)/(3*(4-5))) */
+ a.value = 1; a.operator = OP_IDENTITY; a.left = a.right = NULL;
+ b.value = 2; b.operator = OP_IDENTITY; b.left = b.right = NULL;
+ c.value = 3; c.operator = OP_IDENTITY; c.left = c.right = NULL;
+ d.value = 4; d.operator = OP_IDENTITY; d.left = d.right = NULL;
+ e.value = 5; e.operator = OP_IDENTITY; e.left = e.right = NULL;
+
+ o1.left = &a;
+ o1.right = &b;
+ o1.operator = OP_ADD;
+
+ o2.left = &d;
+ o2.right = &e;
+ o2.operator = OP_SUBTRACT;
+
+ o3.left = &c;
+ o3.right = &o2;
+ o3.operator = OP_MULTIPLY;
+
+ o4.left = &o1;
+ o4.right = &o3;
+ o4.operator = OP_DIVIDE;
+
+ dump_tree(&o4);
+ printf("\n = %f\n", evaluate(&o4));
+}