ein_sol.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. function EV() {
  2. this.__e = {};
  3. }
  4. EV.prototype.__e = {};
  5. EV.prototype.emit = function(n) {
  6. var that = this;
  7. var args = [].slice.apply(arguments, [1]);
  8. (this.__e[n] || []).map(function(lis) {
  9. lis.map(function(fn) {
  10. fn.apply(that, args)
  11. })
  12. })
  13. return this;
  14. }
  15. EV.prototype.on = function(n) {
  16. var args = [].slice.apply(arguments, [1]);
  17. this.__e[n] = this.__e[n] || [];
  18. this.__e[n].push(args);
  19. return this;
  20. }
  21. function inherits(ctor, superCtor) {
  22. var Obj = function() {};
  23. Obj.prototype = superCtor.prototype;
  24. ctor.prototype = new Obj
  25. }
  26. function permutates(xs) {
  27. var ret = [];
  28. for (var i = 0; i < xs.length; i = i + 1) {
  29. var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
  30. if (!rest.length) {
  31. ret.push([xs[i]])
  32. } else {
  33. for (var j = 0; j < rest.length; j = j + 1) {
  34. ret.push([xs[i]].concat(rest[j]))
  35. }
  36. }
  37. }
  38. return ret;
  39. }
  40. function mo() {
  41. this.variabler = {};
  42. this.tabel = {};
  43. this.tableHead = [];
  44. this.tableName = "";
  45. this.regler = [];
  46. this._internal_step_counter = 0;
  47. this.rmat = [];
  48. this.funcs = {};
  49. this.rulas = [];
  50. }
  51. inherits(mo, EV)
  52. mo.prototype.addVariabelSet = function(navn, arr) {
  53. this.variabler[navn] = arr;
  54. return this;
  55. }
  56. mo.prototype.addVariableTable = function(navn, arr) {
  57. this.tableHead = arr;
  58. this.tableName = navn;
  59. return this;
  60. }
  61. mo.prototype.addFunction = function(name, func) {
  62. this.funcs[name] = func;
  63. return this;
  64. }
  65. mo.prototype.addClause = function() {
  66. var args = Array.prototype.slice.apply(arguments, []);
  67. while (args.length) {
  68. var arg = args.shift();
  69. var props = Object.keys(arg);
  70. var propid1, propid2;
  71. if (this.variabler[props[0]]) {
  72. propid1 = Object.keys(this.variabler).indexOf(props[0]);
  73. }
  74. if (this.variabler[props[1]]) {
  75. propid2 = Object.keys(this.variabler).indexOf(props[1]);
  76. } else {}
  77. var arr = []
  78. if (propid1 > -1 && propid2 > -1) {
  79. val1 = this.variabler[props[0]].indexOf(arg[props[0]])
  80. val2 = this.variabler[props[1]].indexOf(arg[props[1]])
  81. arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
  82. } else {
  83. var lookfor = props[props.length - 1];
  84. if (this.funcs[lookfor]) {
  85. arr = this.funcs[lookfor].apply(this, [arg])
  86. }
  87. }
  88. }
  89. this.rulas.push(arr);
  90. return this;
  91. }
  92. mo.prototype.build = function(tabl) {
  93. var r = [];
  94. var arr = [];
  95. var pertable = []
  96. for (var navn in this.variabler) {
  97. pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
  98. return i
  99. })));
  100. }
  101. return pertable;
  102. }
  103. mo.prototype.checkn = function(prop1, prop2, val1, val2) {
  104. return this.current[this.sos[prop1]][val1] == val2
  105. }
  106. mo.prototype.check = function(prop1, prop2, val1, val2) {
  107. var i;
  108. // console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
  109. for (i = 0; i < 5; i++) {
  110. if (this.current[this.sos[prop1]][i] == val1) {
  111. // console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
  112. var p;
  113. p = (this.current[this.sos[prop2]][i] == val2)
  114. return p;
  115. }
  116. }
  117. return false;
  118. }
  119. mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
  120. var i;
  121. for (i = 0; i < 4; i++) {
  122. if (this.current[this.sos[prop1]][i] == val1) {
  123. var p;
  124. p = (this.current[this.sos[prop2]][i + 1] == val2)
  125. return p;
  126. }
  127. }
  128. return false;
  129. }
  130. mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
  131. var i;
  132. for (i = 1; i < 5; i++) {
  133. if (this.current[this.sos[prop1]][i] == val1) {
  134. var p;
  135. p = (this.current[this.sos[prop2]][i - 1] == val2)
  136. return p;
  137. }
  138. }
  139. return false;
  140. }
  141. mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
  142. return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
  143. }
  144. mo.prototype.solve = function() {
  145. var self = this;
  146. self.current = this.build("House").shift();
  147. var sa = Object.keys(this.variabler);
  148. self.sos = sa.map(function(a) {
  149. return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
  150. })
  151. self.subspace = self.current.length;
  152. self.varspace = sa.length;
  153. self.space = Math.pow(self.subspace, self.varspace);
  154. var iteration = 0;
  155. var maxi = 0;
  156. var ioa = -1;
  157. var soso = [];
  158. var sat = false;
  159. self.rulas = self.rulas;//slice(0, 9);
  160. /* self.rulas.sort(function(a, b) {
  161. return a[1] > b[1] ? -1 : a[1] < b[1] ? 1 : a[2] > b[2] ? 1 : a[2] < b[2] ? -1 : 0
  162. })
  163. */
  164. // console.log(self.rulas);
  165. // return false;
  166. var iomax = self.rulas.length;
  167. while (!sat && iteration < self.space) {
  168. var io = 0;
  169. var ff = true;
  170. while (io < iomax && ff) {
  171. var t = self.rulas[io];
  172. ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
  173. if(ff){
  174. io++;
  175. }
  176. }
  177. if (io > ioa) {
  178. soso.push([].concat(self.sos));
  179. ioa = io;
  180. var tt = self.rulas.map(function(t) {
  181. return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
  182. })
  183. console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
  184. return a.join(" ")
  185. }));
  186. }
  187. if (io >= iomax) {
  188. sat = true;
  189. // console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
  190. } else {
  191. self.sos[4] = iteration % self.subspace;
  192. self.sos[1] = Math.floor(iteration / self.subspace) % self.subspace;
  193. self.sos[2] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
  194. self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
  195. self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
  196. }
  197. if (iteration % 10000000 === 0) {
  198. // console.log((iteration/1000000).toFixed(0)+"m", ioa,"::", self.sos.join(" "));
  199. self.emit("status", (iteration / (self.space / 100)).toFixed(2), self.sos.join(" ") )
  200. }
  201. iteration++;
  202. }
  203. if (sat) {
  204. console.log("SOLUTION FOUND");
  205. }
  206. var tt = self.rulas.map(function(t) {
  207. return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
  208. })
  209. console.log(iteration, io, ioa, self.sos.join(" "), tt.map(function(a) {
  210. return a.join(" ")
  211. }));
  212. self.printit()
  213. }
  214. mo.prototype.printit = function() {
  215. var lpad = function(s, l) {
  216. while (s.length < l) {
  217. s = " " + s
  218. };
  219. return s;
  220. }
  221. var rpad = function(s, l) {
  222. while (s.length < l) {
  223. s = s + " "
  224. };
  225. return s;
  226. }
  227. var self = this;
  228. var s = [];
  229. s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
  230. return lpad("" + a, 12)
  231. }).join(" "));
  232. Object.keys(self.variabler).map(function(k, ia) {
  233. s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
  234. return a == k ? rpad(k + ":" + self.sos[ia], 20) : lpad("" + self.variabler[k][self.current[self.sos[ia]][a]], 12)
  235. }).join(" "))
  236. // s.push( )
  237. })
  238. console.log(s.join("\n") + "\n")
  239. }
  240. mo.prototype.stats = function() {
  241. console.log("steps ", this._internal_step_counter)
  242. console.log(this);
  243. }
  244. var t = new mo()
  245. .addVariabelSet("Nationality", ["Norwegian", "Dane", "Englishman", "German","Swede"])
  246. .addVariabelSet("Color", ["Red","Green", "White", "Yellow", "Blue" ])
  247. .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
  248. .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
  249. .addVariabelSet("Animals", ["Dogs", "Birds", "Cats", "Horses", "Fish"])
  250. .addVariableTable("House", [0, 1, 2, 3, 4])
  251. .addFunction("Neighbor", function(arg) {
  252. var prop1 = Object.keys(arg)[0];
  253. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  254. var val1 = arg[prop1];
  255. var val2 = arg["Neighbor"][prop2];
  256. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  257. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  258. var valid1 = (this.variabler[prop1]).indexOf(val1)
  259. var valid2 = (this.variabler[prop2]).indexOf(val2)
  260. return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
  261. })
  262. .addFunction("Neighbor_Before", function(arg) {
  263. var prop1 = Object.keys(arg)[0];
  264. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  265. var val1 = arg[prop1];
  266. var val2 = arg["Neighbor_Before"][prop2];
  267. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  268. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  269. var valid1 = (this.variabler[prop1]).indexOf(val1)
  270. var valid2 = (this.variabler[prop2]).indexOf(val2)
  271. return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
  272. })
  273. .addFunction("Neighbor_After", function() {
  274. var prop1 = Object.keys(arg)[0];
  275. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  276. var val1 = arg[prop1];
  277. var val2 = arg["Neighbor_After"][prop2];
  278. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  279. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  280. var valid1 = (this.variabler[prop1]).indexOf(val1)
  281. var valid2 = (this.variabler[prop2]).indexOf(val2)
  282. return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
  283. })
  284. .addFunction("House", function(arg) {
  285. var prop1 = Object.keys(arg)[0];
  286. var prop2 = prop1
  287. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  288. var val1 = arg[prop1];
  289. var val2 = arg["House"];
  290. var valid1 = (this.variabler[prop1]).indexOf(val1)
  291. return ['checkn', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
  292. })
  293. .addClause({
  294. "Nationality": "Norwegian",
  295. "House": 0
  296. })
  297. .addClause({
  298. "Drinks": "Milk",
  299. "House": 2
  300. })
  301. .addClause({
  302. "Nationality": "Norwegian",
  303. "Neighbor": {
  304. "Color": "Blue"
  305. }
  306. })
  307. .addClause({
  308. "Nationality": "Englishman",
  309. "Color": "Red"
  310. })
  311. .addClause({
  312. "Smokes": "Blend",
  313. "Neighbor": {
  314. "Drinks": "Water"
  315. }
  316. })
  317. .addClause({
  318. "Nationality": "Swede",
  319. "Animals": "Dogs"
  320. })
  321. .addClause({
  322. "Nationality": "Dane",
  323. "Drinks": "Tea"
  324. })
  325. .addClause({
  326. "Color": "Green",
  327. "Neighbor_Before": {
  328. "Color": "White"
  329. }
  330. })
  331. .addClause({
  332. "Color": "Green",
  333. "Drinks": "Coffee"
  334. })
  335. .addClause({
  336. "Smokes": "PallMall",
  337. "Animals": "Birds"
  338. })
  339. .addClause({
  340. "Color": "Yellow",
  341. "Smokes": "Dunhill"
  342. })
  343. .addClause({
  344. "Nationality": "German",
  345. "Smokes": "Prince"
  346. })
  347. .addClause({
  348. "Smokes": "Blend",
  349. "Neighbor": {
  350. "Animals": "Cats"
  351. }
  352. })
  353. .addClause({
  354. "Animals": "Horses",
  355. "Neighbor": {
  356. "Smokes": "Dunhill"
  357. }
  358. })
  359. .addClause({
  360. "Smokes": "BlueMasters",
  361. "Drinks": "Bier"
  362. })
  363. /* .addClause("$House('Nationality','Norwegian')","eq","$House().first")
  364. .addClause("$House('Drinks','Milk')","eq","$House().mid")
  365. .addClause("$House('Nationality','Englishman')","eq","$House('Color','Red')")
  366. .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
  367. */
  368. /*.addClause(0,"Norwegian",-1,-1,-1,-1)
  369. .addClause(2,-1,-1,-1,"Milk",-1)
  370. .addClause(-1,"Englishman","Red",-1,-1,-1,-1)
  371. .addClause(-1,"N Norwegian","Blue",-1,-1,-1,-1)
  372. .addClause("Math.abs($House('Nationality','Norwegian') - $House('Color','Blue'))===1")
  373. .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
  374. .addClause("$House('Nationality','Swede')===$House('Animals','Dogs')")
  375. .addClause("$House('Nationality','Dane')===$House('Drinks','Tea')")
  376. .addClause("($House('Color','Green')+1)===$House('Color','White')")
  377. .addClause("$House('Color','Green')===$House('Drinks','Coffee')")
  378. .addClause("$House('Smokes','PallMall')===$House('Animals','Birds')")
  379. .addClause("$House('Color','Yellow')===$House('Smokes','Dunhill')")
  380. .addClause("Math.abs($House('Smokes','Blend')-$House('Animals','Cats'))===1")
  381. .addClause("$House('Smokes','BlueMasters')===$House('Drinks','Bier')")
  382. //.addClause("Math.abs($House('Animals','Horses')-$House('Smokes','Dunhill'))===1")
  383. //.addClause("$House('Nationality','German')===$House('Smokes','Prince')")
  384. */
  385. /*
  386. The Englishman lives in the red house.<br>
  387. The Swede keeps dogs.<br>
  388. The Dane drinks tea.<br>
  389. The green house is just to the left of the white one.<br>
  390. The owner of the green house drinks coffee.<br>
  391. The Pall Mall smoker keeps birds.<br>
  392. The owner of the yellow house smokes Dunhills.<br>
  393. The man in the center house drinks milk.<br>
  394. The Norwegian lives in the first house.<br>
  395. The Blend smoker has a neighbor who keeps cats.<br>
  396. The man who smokes Blue Masters drinks bier.<br>
  397. The man who keeps horses lives next to the Dunhill smoker.<br>
  398. The German smokes Prince.<br>
  399. The Norwegian lives next to the blue house.<br>
  400. The Blend smoker has a neighbor who drinks water.<br>
  401. */
  402. //console.log(t.randoma("House"));
  403. //t.stats();
  404. t.on("status", function(per, found) {
  405. console.log("PER", per, found);
  406. })
  407. t.solve();
  408. /*
  409. var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
  410. Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
  411. Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
  412. Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
  413. Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/