Skip to content

Instantly share code, notes, and snippets.

@jacklehamster
Created May 16, 2018 04:41
Show Gist options
  • Save jacklehamster/6ac8226158939f4acd18c4187e99fb7c to your computer and use it in GitHub Desktop.
Save jacklehamster/6ac8226158939f4acd18c4187e99fb7c to your computer and use it in GitHub Desktop.
Implementation of a solver for the game Le Compte Est Bon
var nums = new Array(6).fill(null).map(a => (Math.floor(Math.random()*9 + 1) * (Math.random()<.4?10:1)));
var goal = Math.floor(Math.random()*900 + 100);
console.log(`goal = ${goal}`);
console.log(`nums = ${nums}\n`);
const bag = [];
nums.forEach((num, index) => {
bag.push(
{
num,
mask: 1<<index,
children: null,
}
);
});
const bagHash = {};
function checkBagHash(item) {
if(item.num === goal) {
found = true;
}
if (!bagHash[item.num+","+item.mask]) {
bagHash[item.num+","+item.mask] = item;
return true;
}
return false;
}
var found = false;
for(var i=0; i<bag.length && !found; i++) {
for(var j=0; j<bag.length && !found; j++) {
if((bag[i].mask & bag[j].mask) === 0) {
var item = {
num: bag[i].num + bag[j].num,
mask: bag[i].mask | bag[j].mask,
operator: '+',
children: [bag[i], bag[j]],
};
if(checkBagHash(item)) {
bag.push(item);
}
var item = {
num: Math.abs(bag[i].num - bag[j].num),
mask: bag[i].mask | bag[j].mask,
operator: '-',
children: [bag[i], bag[j]],
};
if(checkBagHash(item)) {
bag.push(item);
}
var item = {
num: bag[i].num * bag[j].num,
mask: bag[i].mask | bag[j].mask,
operator: 'x',
children: [bag[i], bag[j]],
};
if(checkBagHash(item)) {
bag.push(item);
}
if(bag[i].num%bag[j].num===0 || bag[j].num%bag[i].num===0) {
var item = {
num: Math.max(bag[i].num / bag[j].num, bag[j].num / bag[i].num),
mask: bag[i].mask | bag[j].mask,
operator: '/',
children: [bag[i], bag[j]],
};
if(checkBagHash(item)) {
bag.push(item);
}
}
}
}
}
const opLevel = {
'+': 1, '-': 1, 'x':2, '/':2,
};
const orderMatter = {
'-': true, '/': true,
};
function expression(item, parentOperator, left) {
if(!item.children) {
return item.num;
}
const a = item.children[0];
const b = item.children[1];
let exp = null;
if(a.num>b.num) {
exp = `${expression(a,item.operator, true)} ${item.operator} ${expression(b,item.operator, false)}`;
} else {
exp = `${expression(b,item.operator, true)} ${item.operator} ${expression(a,item.operator, false)}`;
}
if(opLevel[parentOperator] > opLevel[item.operator] || !left && orderMatter[parentOperator]) {
exp = `(${exp})`;
}
return exp;
}
let best = bag[0];
for(let i=1; i<bag.length; i++) {
if(Math.abs(goal-bag[i].num) < Math.abs(best.num-goal)) {
best = bag[i]
}
}
const exp = expression(best);
console.log(exp, "=", eval(exp.split("x").join("*")));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment