Skip to content

Instantly share code, notes, and snippets.

@thekoushik
Last active November 9, 2016 06:30
Show Gist options
  • Save thekoushik/0cd272365ac69d45588e5e25ace0dcca to your computer and use it in GitHub Desktop.
Save thekoushik/0cd272365ac69d45588e5e25ace0dcca to your computer and use it in GitHub Desktop.
Impossible Math
/*
The Impossible Math Solver
There will be a predefined target and the process will start with 2 numbers. There will be a set
of predefined operations from which any operation can be used any number of times in any order.
Each operation will accept 2 numbers. First one is the output of the previous operation and the
second one is any number generated from previous operations. Generated numbers must be unique.
The goal is to create a list of operation where the last operation will generate the predefined
target.
usage:
var operations=[
{name:"add",body:function(i,j){return i+j;} },
{name:"sub",body:function(i,j){return i-j;} },
{name:"mul",body:function(i,j){return i*j;} },
{name:"div",body:function(i,j){return i/j;} },
];
var ImpossibleMath=require('./impossible');
var imp=new ImpossibleMath(5,4,19,operations);
console.log(!imp.execute(500)?"Limit Exceeded!":imp.result().join("\n"));
*/
(function(){
/*
Author: Koushik Seal
param1 = first:number
param2 = second:number
param3 = target:number
param4 = operation:array => operation = {name:string,body:function(a,b){ ... return ...;}}
param5 = iteration limit(optional)(default=100)
*/
function Impossible(a,b,c,d,limit){
this.__nums=[a,b];
this.__target=c;
this.__operations=d;
this.__output=[];
this.__limit=(limit==undefined)?100:limit;
}
Impossible.prototype.result = function() {
return this.__output;
};
Impossible.prototype.__do_operation=function(i,j){
return this.__operations[i].body(this.__nums[this.__nums.length-1],this.__nums[j]);
}
Impossible.prototype.__decide=function(i,j){
var o=this.__do_operation(i,j);
return (this.__nums.indexOf(o)<0 && o>0)?o:null;
}
Impossible.prototype.__dist=function(a){
return Math.abs(this.__target-a);
}
Impossible.prototype.__analyse=function (){
var func=0,ind=0,i,j;
var diff=0;
var min_dist1=null,min_dist2=null;
for(i=0;i<this.__nums.length-1;i++){
for(j=0;j<this.__operations.length;j++){
var temp=this.__decide(j,i);
if(temp==null) continue;
else if(temp==this.__target) return {func:j,ind:i};
var dist_temp=this.__dist(temp);
if(!min_dist1)
min_dist1={func:j,ind:i,val:dist_temp};
else if(min_dist1.val>dist_temp)
min_dist1={func:j,ind:i,val:dist_temp};
if(this.__nums.indexOf(dist_temp)>=0)
return {func:j,ind:i};
if(!min_dist2)
min_dist2={func:j,ind:i,val:dist_temp};
else if(min_dist2.val>dist_temp)
min_dist2={func:j,ind:i,val:dist_temp};
}
}
return (min_dist1)?min_dist1:min_dist2;
}
Impossible.prototype.__goal=function(analysed){
var o=this.__do_operation(analysed.func,analysed.ind);
this.__output.push(this.__operations[analysed.func].name+"("+this.__nums[this.__nums.length-1]+","+this.__nums[analysed.ind]+") = "+o);
this.__nums.push(o);
return (o==this.__target);
}
Impossible.prototype.execute=function(limit){
var iter=0;
this.__output=[];
var lim=(limit==undefined)?this.__limit:limit;
while(iter++<lim)
if(this.__goal(this.__analyse()))
return true;
return false;
}
try{module.exports=Impossible;}catch(e){window.Impossible=Impossible;}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment