SHARE
TWEET

Untitled

a guest Mar 26th, 2019 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Operation() {
  2.     this.operands = arguments;
  3. }
  4.  
  5. Operation.prototype.evaluate = function () {
  6.     var result = [];
  7.     for (var i = 0; i < this.operands.length; i++) {
  8.         result.push(this.operands[i].evaluate.apply(this.operands[i], arguments));
  9.     }
  10.     return this.count.apply(null, result);
  11. };
  12.  
  13. Operation.prototype.diff = function (name) {
  14.     var result = [];
  15.     for (var i = 0; i < this.operands.length; i++) {
  16.         result.push(this.operands[i]);
  17.         result.push(this.operands[i].diff(name));
  18.     }
  19.     return this.countDiff.apply(null, result);
  20. };
  21.  
  22. Operation.prototype.toString = function () {
  23.     var resString = '';
  24.     for (var i = 0; i < this.operands.length; i++) {
  25.         resString += this.operands[i].toString() + ' ';
  26.     }
  27.     return resString + this.operation;
  28. };
  29.  
  30. function Const(a) {
  31.     this.value = a;
  32. }
  33.  
  34. Const.prototype.evaluate = function () {
  35.     return this.value;
  36. };
  37.  
  38. Const.prototype.diff = function (name) {
  39.     return new Const(0);
  40. };
  41.  
  42. Const.prototype.toString = function () {
  43.     return this.value.toString();
  44. };
  45.  
  46. var vars = ['x', 'y', 'z'];
  47.  
  48. function Variable(name) {
  49.     this.index = vars.indexOf(name);
  50. }
  51.  
  52. Variable.prototype.evaluate = function () {
  53.     return arguments[this.index];
  54. };
  55.  
  56. Variable.prototype.diff = function (name) {
  57.     if (vars[this.index] === name) {
  58.         return new Const(1);
  59.     }
  60.     else {
  61.         return new Const(0);
  62.     }
  63. };
  64.  
  65. Variable.prototype.toString = function () {
  66.     return vars[this.index];
  67. };
  68.  
  69. function Add(a, b) {
  70.     Operation.call(this, a, b);
  71.     this.operation = '+'
  72. }
  73.  
  74. Add.prototype = Object.create(Operation.prototype);
  75. Add.prototype.count = function (a, b) {
  76.     return a + b;
  77. }
  78. Add.prototype.countDiff = function (a, a_dir, b, b_dir) {
  79.     return new Add(a_dir, b_dir);
  80. };
  81.  
  82. function Subtract(a, b) {
  83.     Operation.call(this, a, b);
  84.     this.operation = '-'
  85. }
  86.  
  87. Subtract.prototype = Object.create(Operation.prototype);
  88. Subtract.prototype.count = function (a, b) {
  89.     return a - b;
  90. };
  91. Subtract.prototype.countDiff = function (a, a_dir, b, b_dir) {
  92.     return new Subtract(a_dir, b_dir);
  93. };
  94.  
  95. function Multiply(a, b) {
  96.     Operation.call(this, a, b);
  97.     this.operation = '*'
  98. }
  99.  
  100. Multiply.prototype = Object.create(Operation.prototype);
  101. Multiply.prototype.count = function (a, b) {
  102.     return a * b;
  103. };
  104. Multiply.prototype.countDiff = function (a, a_dir, b, b_dir) {
  105.     return new Add(new Multiply(a, b_dir), new Multiply(a_dir, b));
  106. };
  107.  
  108. function Divide(a, b) {
  109.     Operation.call(this, a, b);
  110.     this.operation = '/'
  111. }
  112.  
  113. Divide.prototype = Object.create(Operation.prototype);
  114. Divide.prototype.count = function (a, b) {
  115.     return a / b;
  116. };
  117. Divide.prototype.countDiff = function (a, a_dir, b, b_dir) {
  118.     return new Divide(new Subtract(new Multiply(a_dir, b), new Multiply(a, b_dir)), new Multiply(b, b));
  119. };
  120.  
  121. function Negate(a) {
  122.     Operation.call(this, a);
  123.     this.operation = 'negate'
  124. }
  125.  
  126. Negate.prototype = Object.create(Operation.prototype);
  127. Negate.prototype.count = function (a) {
  128.     return -a;
  129. };
  130. Negate.prototype.countDiff = function (a, a_dir) {
  131.     return new Negate(a_dir);
  132. };
  133.  
  134. function ArcTan(a) {
  135.     Operation.call(this, a);
  136.     this.operation = 'atan';
  137. }
  138.  
  139. ArcTan.prototype = Object.create(Operation.prototype);
  140. ArcTan.prototype.count = function (a) {
  141.     return Math.atan(a);
  142. };
  143. ArcTan.prototype.countDiff = function (a, da) {
  144.     return new Divide(da, new Add(new Const(1), new Multiply(a, a)));
  145. };
  146.  
  147. function ArcTan2(a, b) {
  148.     Operation.call(this, a, b);
  149.     this.operation = 'atan2';
  150. }
  151.  
  152. ArcTan2.prototype = Object.create(Operation.prototype);
  153. ArcTan2.prototype.count = function (a, b) {
  154.     return Math.atan2(a, b);
  155. };
  156. ArcTan2.prototype.countDiff = function (arguments) {
  157.     return new Divide(new Subtract(new Multiply(arguments[2], arguments[1]), new Multiply(arguments[0],
  158.         arguments[3])), new Add(new Multiply(arguments[0], arguments[0]), new Multiply(arguments[1], arguments[1])));
  159. }
  160.  
  161. function applyToConstructor(constructor, argArray) {
  162.     var args = [null].concat(argArray);
  163.     var factoryFunction = constructor.bind.apply(constructor, args);
  164.     return new factoryFunction();
  165. }
  166.  
  167. function isDigit(c) {
  168.     return c >= '0' && c <= '9';
  169. }
  170.  
  171. function parse(expr) {
  172.     var OPERATIONS = {
  173.         '+': [Add, 2],
  174.         '-': [Subtract, 2],
  175.         '*': [Multiply, 2],
  176.         '/': [Divide, 2],
  177.         'negate': [Negate, 1],
  178.         'atan': [ArcTan, 1],
  179.         'atan2': [ArcTan2, 2]
  180.     };
  181.     var stack = [];
  182.     var tokens = expr.split(/\s+/);
  183.     for (var i = 0; i < tokens.length; i++) {
  184.         var token = tokens[i];
  185.         if (token in OPERATIONS) {
  186.             var args = [];
  187.             for (var j = 0; j < OPERATIONS[token][1]; j++)
  188.                 args.unshift(stack.pop());
  189.             stack.push(applyToConstructor(OPERATIONS[token][0], args));
  190.         } else if (vars.indexOf(token) !== -1) {
  191.             stack.push(new Variable(token));
  192.         } else if (isDigit(tokens[i][0]) || (tokens[i][0] === '-' && tokens[i].length !== 1)) {
  193.             stack.push(new Const(parseInt(token)));
  194.         }
  195.     }
  196.     return stack.pop();
  197. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top