ein.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. // var mo = require("./solver");
  2. /*
  3. .addVariabelSet("Nationality", ["Norwegian", "German", "Dane", "Swede", "Englishman"])
  4. .addVariabelSet("Color", ["Yellow", "Red", "White", "Blue", "Green"])
  5. .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
  6. .addVariabelSet("Drinks", ["Bier", "Water", "Coffee", "Milk", "Tea"])
  7. .addVariabelSet("Animals", ["Birds", "Dogs", "Cats", "Horses", "Fish","Snake"])
  8. */
  9. function EV() {
  10. this.__e = {};
  11. }
  12. EV.prototype.__e = {};
  13. EV.prototype.emit = function(n) {
  14. var that = this;
  15. var args = [].slice.apply(arguments, [1]);
  16. (this.__e[n] || []).map(function(lis) {
  17. lis.map(function(fn) {
  18. fn.apply(that, args)
  19. })
  20. })
  21. return this;
  22. }
  23. EV.prototype.on = function(n) {
  24. var args = [].slice.apply(arguments, [1]);
  25. this.__e[n] = this.__e[n] || [];
  26. this.__e[n].push(args);
  27. return this;
  28. }
  29. function inherits(ctor, superCtor) {
  30. var Obj = function() {};
  31. Obj.prototype = superCtor.prototype;
  32. ctor.prototype = new Obj
  33. }
  34. function permutates(xs) {
  35. var ret = [];
  36. for (var i = 0; i < xs.length; i = i + 1) {
  37. var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
  38. if (!rest.length) {
  39. ret.push([xs[i]])
  40. } else {
  41. for (var j = 0; j < rest.length; j = j + 1) {
  42. ret.push([xs[i]].concat(rest[j]))
  43. }
  44. }
  45. }
  46. return ret;
  47. }
  48. function mo() {
  49. this.variabler = {};
  50. this.funcs = {};
  51. this.rulas = [];
  52. }
  53. inherits(mo, EV)
  54. mo.prototype.addVariabelSet = function(navn, arr) {
  55. this.variabler[navn] = arr
  56. return this;
  57. }
  58. mo.prototype.addVariableTable = function(navn, arr) {
  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. pertable = pertable.sort(function(a,b){ return a.length > b.length ? 1 : a.length < b.length ? -1 : 0 });
  102. pertable.map(function(a){
  103. console.log("A",a.length)
  104. })
  105. return pertable.pop()
  106. }
  107. mo.prototype.checkPos = function(prop1, prop2, val1, val2) {
  108. return this.current[this.sos[prop1]][val2] == val1
  109. }
  110. mo.prototype.check = function(prop1, prop2, val1, val2) {
  111. var i;
  112. // console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
  113. for (i = 0; i < 5; i++) {
  114. if (this.current[this.sos[prop1]][i] == val1) {
  115. // console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
  116. var p;
  117. p = (this.current[this.sos[prop2]][i] == val2)
  118. return p;
  119. }
  120. }
  121. return false;
  122. }
  123. mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
  124. var i;
  125. for (i = 0; i < 4; i++) {
  126. if (this.current[this.sos[prop1]][i] == val1) {
  127. var p;
  128. p = (this.current[this.sos[prop2]][i + 1] == val2)
  129. return p;
  130. }
  131. }
  132. return false;
  133. }
  134. mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
  135. var i;
  136. for (i = 1; i < 5; i++) {
  137. if (this.current[this.sos[prop1]][i] == val1) {
  138. var p;
  139. p = (this.current[this.sos[prop2]][i - 1] == val2)
  140. return p;
  141. }
  142. }
  143. return false;
  144. }
  145. mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
  146. return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
  147. }
  148. /*
  149. mo.prototype.inner_solve_l_1 = function(cands) {
  150. }
  151. mo.prototype.inner_solve_l_2 = function(cands) {
  152. }
  153. mo.prototype.inner_solve_l_3 = function(cands) {
  154. }
  155. mo.prototype.inner_solve_l_4 = function(cands) {
  156. }
  157. mo.prototype.inner_solve_l_5 = function(cands) {
  158. }
  159. */
  160. mo.prototype.inner_solve = function(cands) {
  161. /*todo tada - slip fri for for for for for */
  162. var self = this;
  163. var cc = cands.length;
  164. var ticks = [0, 0, 0, 0, 0];
  165. var ic = 0;
  166. var iomax = self.rulas.length;
  167. var ioa = 0;
  168. var suma = cands.reduce(function(a, b) {
  169. return b[1].length * a
  170. }, 1)
  171. console.log(cands);
  172. console.log(this.rulas);
  173. return;
  174. for (var i0 = 0; i0 < cands[0][1].length; i0++) {
  175. if (cands[1]) {
  176. for (var i1 = 0; i1 < cands[1][1].length; i1++) {
  177. if (cands[2]) {
  178. for (var i2 = 0; i2 < cands[2][1].length; i2++) {
  179. if (cands[3]) {
  180. } else {
  181. total = suma * self.subspace * self.subspace
  182. var st = [0, 1, 2, 3, 4]
  183. self.sos[cands[0][0]] = cands[0][1][i0]
  184. self.sos[cands[1][0]] = cands[1][1][i1]
  185. self.sos[cands[2][0]] = cands[2][1][i2]
  186. st.splice(st.indexOf(cands[0][0]), 1);
  187. st.splice(st.indexOf(cands[1][0]), 1);
  188. st.splice(st.indexOf(cands[2][0]), 1);
  189. for (var i3 = 0; i3 < self.subspace; i3++) {
  190. for (var i4 = 0; i4 < self.subspace; i4++) {
  191. ic++
  192. self.sos[st[0]] = i3
  193. self.sos[st[1]] = i4
  194. var io = 0;
  195. var ff = true;
  196. while (io < iomax && ff) {
  197. ff = false;
  198. var t = self.rulas[io];
  199. ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
  200. if (ff) {
  201. io++;
  202. }
  203. }
  204. if (io > ioa) {
  205. ioa = io;
  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. self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
  210. return a.join(" ")
  211. }))
  212. }
  213. if (ioa >= iomax) {
  214. return self.sos;
  215. }
  216. if (ic % 1000000 === 0) {
  217. self.emit("status", (ic / (total / 100)).toFixed(2) + "%", total, ic, ioa, iomax)
  218. // console.log("X2", ic, io, ioa, iomax,":>", self.sos[cands[0][0]], self.sos[cands[1][0]], self.sos[cands[2][0]], i3, i4);
  219. }
  220. }
  221. }
  222. }
  223. }
  224. } else {
  225. var st = [0, 1, 2, 3, 4]
  226. self.sos[cands[0][0]] = cands[0][1][i0]
  227. self.sos[cands[1][0]] = cands[1][1][i1]
  228. // self.sos[cands[2][0]] = cands[2][1][i2]
  229. st.splice(st.indexOf(cands[0][0]), 1);
  230. st.splice(st.indexOf(cands[1][0]), 1);
  231. // st.splice(st.indexOf(cands[2][0]), 1);
  232. total = suma * self.subspace * self.subspace * self.subspace;
  233. for (var i2 = 0; i2 < self.subspace; i2++) {
  234. for (var i3 = 0; i3 < self.subspace; i3++) {
  235. for (var i4 = 0; i4 < self.subspace; i4++) {
  236. ic++
  237. self.sos[st[0]] = i2
  238. self.sos[st[1]] = i3
  239. self.sos[st[2]] = i4
  240. var io = 0;
  241. var ff = true;
  242. while (io < iomax && ff) {
  243. ff = false;
  244. var t = self.rulas[io];
  245. ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
  246. if (ff) {
  247. io++;
  248. }
  249. }
  250. if (io > ioa) {
  251. ioa = io;
  252. var tt = self.rulas.map(function(t) {
  253. return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
  254. })
  255. self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
  256. return a.join(" ")
  257. }))
  258. }
  259. if (ioa >= iomax) {
  260. return self.sos;
  261. }
  262. if (ic % 1000000 === 0) {
  263. console.log("X3", ic, io, ioa, iomax, ":>", self.sos[cands[0][0]], self.sos[cands[1][0]], i2, i3, i4);
  264. }
  265. }
  266. }
  267. }
  268. }
  269. }
  270. }
  271. }
  272. return false;
  273. }
  274. mo.prototype.solve = function() {
  275. var self = this;
  276. self.current = this.build("House");
  277. console.log(self.current);
  278. var sa = Object.keys(this.variabler);
  279. self.sos = sa.map(function(a) {
  280. return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
  281. })
  282. self.subspace = self.current.length;
  283. self.varspace = sa.length;
  284. var iteration = 0;
  285. var maxi = 0;
  286. var ioa = -1;
  287. // først find variabler som bruges i samme opslag.
  288. var tas = {}
  289. var firsta = [];
  290. self.rulas.map(function(ru) {
  291. console.log(ru);
  292. if (ru[1] == ru[2]) {
  293. firsta.push(ru);
  294. }
  295. })
  296. self.sos = self.sos.map(function(a) {
  297. return 0
  298. })
  299. var osa = -1
  300. console.log(firsta);
  301. var cands = [];
  302. for (var x = 0; x < firsta.length; x++) {
  303. self.sos = self.sos.map(function(a) {
  304. return 0
  305. })
  306. var t = firsta[x];
  307. var ca = [];
  308. for (var i = 0; i < self.subspace; i++) {
  309. var ff = false;
  310. self.sos[t[1]] = i
  311. ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
  312. if (ff) {
  313. ca.push(i);
  314. }
  315. }
  316. cands.push([t[1], ca]);
  317. }
  318. self.sos = self.sos.map(function(a) {
  319. return 0
  320. })
  321. var result = this.inner_solve(cands);
  322. this.emit("done", result);
  323. }
  324. mo.prototype.printit = function(vals) {
  325. var self = this;
  326. var vals = vals || self.sos;
  327. var lpad = function(s, l) {
  328. while (s.length < l) {
  329. s = " " + s
  330. };
  331. return s;
  332. }
  333. var rpad = function(s, l) {
  334. while (s.length < l) {
  335. s = s + " "
  336. };
  337. return s;
  338. }
  339. var s = [];
  340. s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
  341. return lpad("" + a, 12)
  342. }).join(" "));
  343. Object.keys(self.variabler).map(function(k, ia) {
  344. s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
  345. return a == k ? rpad(k + ":" + vals[ia], 20) : lpad("" + self.variabler[k][self.current[vals[ia]][a]], 12)
  346. }).join(" "))
  347. })
  348. console.log(s.join("\n") + "\n")
  349. }
  350. module.exports = mo;
  351. var t = new mo()
  352. .addVariabelSet("Nationality", ["Norwegian", "Dane", "Englishman", "German", "Swede"])
  353. .addVariabelSet("Color", ["Yellow", "Blue", "Red", "Green", "White"])
  354. .addVariabelSet("Smokes", ["Dunhill", "Blend", "PallMall", "Prince", "BlueMasters"])
  355. .addVariabelSet("Drinks", ["Water", "Tea", "Milk", "Coffee", "Bier" ])
  356. .addVariabelSet("Animals", ["Cats", "Horses", "Birds", "Fish", "Dogs"])
  357. .addFunction("Neighbor", function(arg) {
  358. var prop1 = Object.keys(arg)[0];
  359. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  360. var val1 = arg[prop1];
  361. var val2 = arg["Neighbor"][prop2];
  362. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  363. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  364. var valid1 = (this.variabler[prop1]).indexOf(val1)
  365. var valid2 = (this.variabler[prop2]).indexOf(val2)
  366. return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
  367. })
  368. .addFunction("Neighbor_Before", function(arg) {
  369. var prop1 = Object.keys(arg)[0];
  370. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  371. var val1 = arg[prop1];
  372. var val2 = arg["Neighbor_Before"][prop2];
  373. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  374. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  375. var valid1 = (this.variabler[prop1]).indexOf(val1)
  376. var valid2 = (this.variabler[prop2]).indexOf(val2)
  377. return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
  378. })
  379. .addFunction("Neighbor_After", function() {
  380. var prop1 = Object.keys(arg)[0];
  381. var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
  382. var val1 = arg[prop1];
  383. var val2 = arg["Neighbor_After"][prop2];
  384. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  385. var propid2 = Object.keys(this.variabler).indexOf(prop2)
  386. var valid1 = (this.variabler[prop1]).indexOf(val1)
  387. var valid2 = (this.variabler[prop2]).indexOf(val2)
  388. return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
  389. })
  390. .addFunction("House", function(arg) {
  391. var prop1 = Object.keys(arg)[0];
  392. var prop2 = prop1
  393. var propid1 = Object.keys(this.variabler).indexOf(prop1)
  394. var val1 = arg[prop1];
  395. var val2 = arg["House"];
  396. var valid1 = (this.variabler[prop1]).indexOf(val1)
  397. return ['checkPos', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
  398. })
  399. .addClause({
  400. "Nationality": "Norwegian",
  401. "House": 0
  402. })
  403. .addClause({
  404. "Drinks": "Milk",
  405. "House": 2
  406. })
  407. .addClause({
  408. "Nationality": "Norwegian",
  409. "Neighbor": {
  410. "Color": "Blue"
  411. }
  412. })
  413. .addClause({
  414. "Nationality": "Englishman",
  415. "Color": "Red"
  416. })
  417. .addClause({
  418. "Smokes": "Blend",
  419. "Neighbor": {
  420. "Drinks": "Water"
  421. }
  422. })
  423. .addClause({
  424. "Nationality": "Swede",
  425. "Animals": "Dogs"
  426. })
  427. .addClause({
  428. "Nationality": "Dane",
  429. "Drinks": "Tea"
  430. })
  431. .addClause({
  432. "Color": "Green",
  433. "Drinks": "Coffee"
  434. })
  435. .addClause({
  436. "Smokes": "PallMall",
  437. "Animals": "Birds"
  438. })
  439. .addClause({
  440. "Color": "Yellow",
  441. "Smokes": "Dunhill"
  442. })
  443. .addClause({
  444. "Nationality": "German",
  445. "Smokes": "Prince"
  446. })
  447. .addClause({
  448. "Smokes": "Blend",
  449. "Neighbor": {
  450. "Animals": "Cats"
  451. }
  452. })
  453. .addClause({
  454. "Animals": "Horses",
  455. "Neighbor": {
  456. "Smokes": "Dunhill"
  457. }
  458. })
  459. .addClause({
  460. "Smokes": "BlueMasters",
  461. "Drinks": "Bier"
  462. })
  463. .addClause({
  464. "Color": "Green",
  465. "Neighbor_Before": {
  466. "Color": "White"
  467. }
  468. })
  469. .on("status", function(per, total, ic, ioa, iomax) {
  470. console.log("Status", per, ic + " of " + total, "sat " + ioa + " of " + iomax);
  471. })
  472. .on("part", function(iterations, foundl, foundt, total, sos, rules) {
  473. this.parts = this.parts || [];
  474. this.parts.push([iterations, foundt, total, sos, rules]);
  475. })
  476. .on("done", function(result) {
  477. if (result) {
  478. console.log("FOUND SOLUTION:", result);
  479. this.printit(result);
  480. if (this.parts && this.parts.length) {
  481. var rr = this.parts.pop();
  482. console.log(rr[4]);
  483. }
  484. } else {
  485. console.log("NO SOLUTION");
  486. console.log("Closest:");
  487. if (this.parts && this.parts.length) {
  488. var rr = this.parts.pop();
  489. // console.log("RRRRR",rr);
  490. this.printit(rr[3])
  491. console.log(rr[4]);
  492. }
  493. }
  494. })
  495. .solve()