function factors(n) {
  result = {};
  for (var f = 1; f <= n; f++) {
    if (n % f == 0) {
      var g = Math.floor(n / f);
      result[f] = true;
      result[g] = true;
      if (f >= g) break;
    }
  }
  return result;
}

function intersection(a, b) {
  result = {};
  for (var f in a) {
    if (f in b) {
      result[f] = true;
    }
  }
  return result;
}

function difference(a, b) {
  result = {};
  for (var f in a) {
    if (!(f in b)) {
      result[f] = true;
    }
  }
  return result;
}

function legalmove(move, available) {
  if (!(move in available)) return false;
  var remaining = intersection(factors(move), available);
  for (var f in remaining) {
    if (f != move) return true;
  }
  return false;
}

function newgame(n) {
  var result = {};
  result.available = {};
  result.taken = {};
  for (var i = 1; i <= n; i++) {
    result.available[i] = true;
  }
  result.size = n
  result.score = 0;
  result.tax = 0;
  result.legal = function(move) {
    return legalmove(move, this.available);
  }
  result.move = function(m) {
    for (var f in factors(m)) {
      if (f in this.available) {
        delete this.available[f];
        if (f == m) {
          this.taken[f] = true;
          this.score += parseInt(f);
        }
        else {
          this.tax += parseInt(f);
        }
      }
    }
  }
  result.finish = function() {
    for (var f in this.available) {
      delete this.available[f];
      this.tax += parseInt(f);
    }
  }
  return result;
}


