JSFiddle - React, Tailwind, and code Playground

by vjeux

HTML

<script src="http://www.numericjs.com/lib/numeric-1.2.6.js"></script>

<!-- Linear Solver by Vjeux <http://blog.vjeux.com> -->

JavaScript

// Open your console to see the result
function example() {
  var W = 500;
  var ra = 1.5;
  var rb = 1;
  
  var system = new LinearSolver();
  system.addEquation(1, 'wa', 1, 'wb', 500);     // wa + wb = W
  system.addEquation(1, 'ha', -1, 'hb', 0);      // wa = wb
  system.addEquation(1, 'ha', -1 / ra, 'wa', 0); // ha = wa / ra
  system.addEquation(1, 'hb', -1 / rb, 'wb', 0); // hb = wb / rb
  system.print();
  console.log(system.solve());
  // {wa: 300, wb: 200, ha: 200, hb: 200} 
}
  
// LinearSolver implementation

function LinearSolver() {
  this.equations = [];
  this.variables = {};
}

// system.addEquation(1, 'wa', 1, 'wb', 500); // wa + wb = 500
LinearSolver.prototype.addEquation = function () {
  var args = Array.prototype.slice.call(arguments);

  // Type Check
  for (var i = 0; i < args.length; i++) {
    if (i % 2 === 1) {
      if (typeof args[i] !== 'string') {
        throw ['Solver', 'Invalid format', 'Should be string', args[i], i, args];
      }
      this.variables[args[i]] = true;
    } else {
      if (typeof args[i] !== 'number') {
        throw ['Solver', 'Invalid format', 'Should be number', args[i], i, args];
      }
    }
  }

  // Reformat
  var eq = {};
  for (var i = 0; i < args.length - 1 /* !!! */ ; i += 2 /* !!! */ ) {
    var number = args[i];
    var variable = args[i + 1];

    eq[variable] = number;
    this.variables[variable] = true;
  }
  eq['__result'] = args[args.length - 1];
  this.equations.push(eq);
}

LinearSolver.prototype.print = function () {
  console.log(Object.keys(this.variables));
  for (var i = 0; i < this.equations.length; i++) {
    var equation = this.equations[i];
    var str = '';
    for (var variable in equation) {
      if (!equation.hasOwnProperty(variable) || variable === '__result') {
        continue;
      }

      var number = equation[variable];

      var sign = '';
      if (number < 0) {
        sign = '-';
      } else if (str !== '') {
        sign = '+';
      }

      str += sign + ' '...