aggixx

Untitled

May 21st, 2017
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // name, lvl, modifiers, weights
  2. var rawData = `MapAtlasMapsHave20PercentQuality 1   "Maps have 20% Quality
  3. Unique Bosses deal 20% increased Damage"    default 1,000
  4. MapAtlasContainsAdditionalRandomBoss    1   Areas are inhabited by an additional Invasion Boss  "hall_of_grandmasters 0
  5. default 1,000"
  6. MapAtlasClustersOfBloodwormBarrels  1   Areas contain 30 additional Clusters of Mysterious Barrels  default 850
  7. MapAtlasPhysicalDamageAndPacks_ 1   "Areas contain additional Monsters that deal Physical Damage
  8. Players and Monsters take 10% increased Physical Damage"    "no_monster_packs 0
  9. default 1,000"
  10. MapAtlasHighValueEnemiesOnOwnTeam   1   Areas contain hunted traitors   "no_monster_packs 0
  11. default 100"
  12. MapAtlasMagicAndRareMapsHaveAdditionalPacks 1   "Magic Maps contain additional Magic Monsters
  13. Rare Maps contain additional Rare Monsters
  14. Normal Maps contain additional Normal Monsters" "unique_map 0
  15. no_monster_packs 0
  16. default 1,000"
  17. MapAtlasMoveAttackCastSpeed 1   "20% increased Player and Monster Movement Speed
  18. 20% increased Monster Attack Speed
  19. 20% increased Monster Cast Speed"   default 1,000
  20. MapAtlasMontersThatConvertOnDeath__ 1   Areas contain additional Monsters that Convert when Killed  "no_monster_packs 0
  21. default 1,000"
  22. MapAtlasUnIDedMapsGrantQuantity 1   "30% increased Quantity of Items found in Unidentified Maps
  23. Found Items drop Identified in Identified Maps
  24. 15% increased Pack Size in Unidentified Maps"   default 1,000
  25. MapAtlasReducedReflectedDamageTakenMirroredRares    1   "Players cannot take Reflected Damage
  26. Areas contain additional Packs with Mirrored Rare Monsters" default 1,000
  27. MapAtlasPlayersDamageDealtAndTakenWhileStationary_  1   "Players deal 100% increased Damage while stationary
  28. Players take 10% increased Damage while stationary" "vaults_of_atziri 0
  29. default 1,000"
  30. MapAtlasFireDamageAndPacks  1   "Areas contain additional Monsters that deal Fire Damage
  31. Players and Monsters take 10% increased Fire Damage"    "no_monster_packs 0
  32. default 1,000"
  33. MapAtlasGroundHaste 1   Areas contain Slipstreams   default 1,000
  34. MapAtlasInstantFlasksAndHealingMonsters 1   "Life and Mana Recovery from Flasks are instant
  35. Areas contain additional Monsters that Heal"    default 1,000
  36. MapAtlasOnslaughtWhenHitAndOnslaughtEffect  1   "Players and Monsters have Onslaught if they have been Hit Recently
  37. 100% increased effect of Onslaught on Players and Monsters" "vaults_of_atziri 0
  38. default 1,000"
  39. MapAtlasColdDamageAndPacks  1   "Areas contain additional Monsters that deal Cold Damage
  40. Players and Monsters take 10% increased Cold Damage"    "no_monster_packs 0
  41. default 1,000"
  42. MapAtlasStrongboxMonstersEnrageAndDrops 1   "Strongbox Monsters have 500% increased Item Quantity
  43. Strongbox Monsters are Enraged
  44. Areas contain an extra Strongbox"   "hall_of_grandmasters 0
  45. no_strongboxes 0
  46. default 1,000"
  47. MapAtlasMagicPackSize   1   30% increased Magic Pack Size   "no_monster_packs 0
  48. default 1,000"
  49. MapAtlasBodyguardsAndBossMapDrops   1   "Unique Bosses are accompanied by Bodyguards
  50. An additional Map drops on Completing Areas"    "no_boss 0
  51. default 1,000"
  52. MapAtlasLightningDamageAndPacks 1   "Areas contain additional Monsters that deal Lightning Damage
  53. Players and Monsters take 10% increased Lightning Damage"   "no_monster_packs 0
  54. default 1,000"
  55. MapAtlasPoisonEffectsAndParasites   1   "Players deal 10% increased Damage for each Poison on them
  56. Players have 5% increased Movement Speed for each Poison on them
  57. Areas contain additional Poisonous Monsters"    default 1,000
  58. MapAtlasRogueExilesDamageAndDropAdditionalJewels    1   "Rogue Exiles deal 20% increased Damage
  59. Rogue Exiles have 20% increased Maximum Life
  60. Rogue Exiles drop 2 additional Jewels
  61. Areas are inhabited by 1 additional Rogue Exile"    "no_monster_packs 0
  62. default 1,000"
  63. MapAtlasCurseEffectOnPlayersAndMonsters 73  "20% reduced Effect of Curses on Monsters
  64. 60% reduced Effect of Curses on Players"    "vaults_of_atziri 0
  65. default 1,000"
  66. MapAtlasContainsZanaMission 73  Areas contain Zana  "unique_map 0
  67. default 200"
  68. MapAtlasMapQualityBonusAlsoAppliesToRarity  73  "Quality bonus of Maps also applies to Rarity of Items found
  69. Unique Bosses have 20% increased Life"  default 1,000
  70. MapAtlasStrongboxesAreCorruptedAndUnided    73  "Strongboxes in Areas are Corrupted
  71. Areas contain an extra Strongbox
  72. Strongboxes in Areas are at least Rare Rarity"  "no_strongboxes 0
  73. default 200"
  74. MapAtlasChaosDamageAndPacks_    73  "Areas contain additional Monsters that deal Chaos Damage
  75. Players and Monsters take 10% increased Chaos Damage"   "no_monster_packs 0
  76. default 1,000"
  77. MapAtlasUniqueMonstersDropCorruptedItems    73  Unique Monsters drop Corrupted Items    "vaults_of_atziri 0
  78. hall_of_grandmasters 0
  79. default 200"
  80. MapAtlasCorruptedMapBossesDropAdditionalVaalItems   78  "Unique Bosses of Corrupted Maps drop an additional Vaal Item
  81. Found Items have a 5% chance to drop Corrupted in Areas"    default 1,000
  82. MapAtlasBloodlinesDropAdditionalCurrency    78  Nemesis Monsters drop 3 additional Currency Items   "no_monster_packs 0
  83. default 200"
  84. MapAtlasFishy   78  Areas are Alluring  default 10`;
  85.  
  86. // tier "enum"
  87. var tier = {
  88.     WHITE: 1,
  89.     YELLOW: 73,
  90.     RED: 78,
  91. };
  92.  
  93. function getSextantCost(tier) {
  94.     switch (tier) {
  95.         case 1:
  96.             return 2.0; // 4 chaos
  97.         case 73:
  98.             return 4.0; // 5 chaos
  99.         case 78:
  100.             return 8.0; // 6 chaos
  101.     }
  102. }
  103.  
  104. var maxIterations = 500000;
  105.  
  106. var mapData = {
  107.     "Shaped Primordial Pool": {
  108.         tier: tier.YELLOW,
  109.         adjacent: [
  110.             "Cavern",
  111.             "Waste Pool",
  112.             "Phantasmagoria",
  113.             "Burial Chambers",
  114.         ]
  115.     },
  116.     "Canyon": {
  117.         tier: tier.YELLOW,
  118.         adjacent: [
  119.             "Waste Pool",
  120.         ]
  121.     },
  122.     "Vaal City": {
  123.         tier: tier.YELLOW,
  124.         adjacent: [
  125.             "Burial Chambers",
  126.             "Vaults of Atziri",
  127.             "Arachnid Tomb",
  128.             "Olmec's Sanctum",
  129.             "Shore",
  130.             "Catacombs",
  131.         ]
  132.     },
  133.     "Arachnid Tomb": {
  134.         tier: tier.YELLOW,
  135.         adjacent: [
  136.             "Vaults of Atziri",
  137.             "Shore",
  138.             "Vaal City",
  139.             "Vaal Pyramid",
  140.         ]
  141.     },
  142.     "Shore": {
  143.         tier: tier.YELLOW,
  144.         adjacent: [
  145.             "Arachnid Tomb",
  146.             "Vaal City",
  147.             "Catacombs",
  148.             "Olmec's Sanctum",
  149.         ]
  150.     },
  151.     "Catacombs": {
  152.         tier: tier.YELLOW,
  153.         adjacent: [
  154.             "Vaal City",
  155.             "Shore",
  156.             "Olmec's Sanctum",
  157.         ]
  158.     },
  159.     "Olmec's Sanctum": {
  160.         tier: tier.YELLOW,
  161.         adjacent: [
  162.             "Vaal City",
  163.             "Shore",
  164.             "Catacombs",
  165.         ]
  166.     },
  167.     "Vaal Pyramid": {
  168.         tier: tier.WHITE,
  169.         adjacent: [
  170.             "Phantasmagoria",
  171.             "Burial Chambers",
  172.             "Marshes",
  173.             "Vaults of Atziri",
  174.             "Arachnid Tomb",
  175.         ]
  176.     },
  177.     "Marshes": {
  178.         tier: tier.WHITE,
  179.         adjacent: [
  180.             "Phantasmagoria",
  181.             "Vaal Pyramid",
  182.         ]
  183.     },
  184.     "Phantasmagoria": {
  185.         tier: tier.WHITE,
  186.         adjacent: [
  187.             "Shaped Primordial Pool",
  188.             "Vaal Pyramid",
  189.             "Marshes",
  190.         ]
  191.     },
  192.     "Burial Chambers": {
  193.         tier: tier.WHITE,
  194.         adjacent: [
  195.             "Shaped Primordial Pool",
  196.             "Vaal Pyramid",
  197.             "Vaults of Atziri",
  198.             "Vaal City",
  199.         ]
  200.     },
  201.     "Cavern": {
  202.         tier: tier.WHITE,
  203.         adjacent: [
  204.             "Shaped Primordial Pool",
  205.             "Waste Pool",
  206.         ]
  207.     },
  208.     "Waste Pool": {
  209.         tier: tier.WHITE,
  210.         adjacent: [
  211.             "Shaped Primordial Pool",
  212.             "Cavern",
  213.             "Canyon",
  214.             "Channel",
  215.         ]
  216.     },
  217.     "Channel": {
  218.         tier: tier.WHITE,
  219.         adjacent: [
  220.             "Waste Pool",
  221.             "Acid Lakes",
  222.             "Mesa",
  223.             "Factory",
  224.         ]
  225.     },
  226.     "Vaults of Atziri": {
  227.         tier: tier.WHITE,
  228.         adjacent: [
  229.             "Burial Chambers",
  230.             "Vaal City",
  231.             "Arachnid Tomb",
  232.             "Vaal Pyramid",
  233.         ]
  234.     },
  235.     "Acid Lakes": {
  236.         tier: tier.WHITE,
  237.         adjacent: [
  238.             "Channel",
  239.             "Factory",
  240.         ]
  241.     },
  242.     "Mesa": {
  243.         tier: tier.WHITE,
  244.         adjacent: [
  245.             "Channel",
  246.         ]
  247.     },
  248.     "Factory": {
  249.         tier: tier.WHITE,
  250.         adjacent: [
  251.             "Channel",
  252.             "Acid Lakes",
  253.         ]
  254.     },
  255. };
  256.  
  257. var goodMods = {
  258.     "MapAtlasFireDamageAndPacks": true,
  259.     "MapAtlasColdDamageAndPacks": true,
  260.     "MapAtlasLightningDamageAndPacks": true,
  261.     "MapAtlasPhysicalDamageAndPacks_": true,
  262.     "MapAtlasChaosDamageAndPacks_": true,
  263.     "MapAtlasMontersThatConvertOnDeath__": true,
  264.     "MapAtlasInstantFlasksAndHealingMonsters": true,
  265.     "MapAtlasMagicAndRareMapsHaveAdditionalPacks": true,
  266.     "MapAtlasHighValueEnemiesOnOwnTeam": true,
  267.     "MapAtlasPoisonEffectsAndParasites": true,
  268.     "MapAtlasClustersOfBloodwormBarrels": true,
  269.     "MapAtlasClustersOfParasiteBarrels": true,
  270.     "MapAtlasClustersOfWealthyBarrels": true,
  271.     "MapAtlasClustersOfBeaconBarrels": true,
  272.     "MapAtlasClustersOfVolatileBarrels": true,
  273.     "MapAtlasMagicPackSize": true,
  274.     "MapAtlasUniqueMonstersDropCorruptedItems": true,
  275.     "MapAtlasBloodlinesDropAdditionalCurrency": true,
  276.     "MapAtlasReducedReflectedDamageTakenMirroredRares": true,
  277.     "MapAtlasStrongboxesAreCorruptedAndUnided": true,
  278.     "MapAtlasStrongboxMonstersEnrageAndDrops": true,
  279. }
  280.  
  281. var parsed = rawData.match(/.+\t.+\t[^\t]+\t[^\t]+\n/g);
  282.  
  283. for (var i = 0; i < parsed.length; i++) {
  284.     var str = parsed[i];
  285.  
  286.     str = str.match(/[^\t]+/g);
  287.  
  288.     parsed[i] = {
  289.         name: str[0],
  290.         level: parseInt(str[1]),
  291.         mods: str[2].match(/[^\n"]+/g),
  292.         weights: str[3].match(/[^\n"]+/g),
  293.     }
  294.  
  295.     var weightsObj = {};
  296.  
  297.     for (var j = 0; j < parsed[i].weights.length; j++) {
  298.         var r = parsed[i].weights[j].split(/\s/);
  299.         weightsObj[r[0]] = parseInt(r[1].replace(",", ""));
  300.     }
  301.  
  302.     parsed[i].weights = weightsObj;
  303. }
  304.  
  305. var maps = {};
  306.  
  307. // Map prototype -------------------------------------------------
  308.  
  309. // constructor
  310.  
  311. function Map(name, tier, adj, activeMod) {
  312.     this.name = name;
  313.     this.tier = tier;
  314.     this.sextantCost = getSextantCost(this.tier);
  315.     //console.log( this.name + " sextant cost is " + this.sextantCost + "c.");
  316.     if (activeMod) {
  317.         for (var mod in parsed) {
  318.             if (mod.name == activeMod) {
  319.                 this.mod = mod;
  320.                 break;
  321.             }
  322.         }
  323.     }
  324.     this.adjacent = adj;
  325.  
  326.     maps[this.name] = this;
  327. }
  328.  
  329. Map.prototype.getBlockedMods = function(log) {
  330.     if (log) {
  331.         console.log("Blocked mods for " + this.name + ":");
  332.     }
  333.     var blocked = {};
  334.     for (var i in this.adjacent) {
  335.         if (this.adjacent[i].mod) {
  336.             if (log) {
  337.                 console.log(this.adjacent[i].name + " blocks " + this.adjacent[i].mod.name);
  338.             }
  339.             blocked[this.adjacent[i].mod.name] = true;
  340.         }
  341.  
  342.         for (var j in this.adjacent[i].adjacent) {
  343.             if (this.adjacent[i].adjacent[j].mod) {
  344.                 if (log) {
  345.                     console.log(this.adjacent[i].adjacent[j].name + " blocks " + this.adjacent[i].adjacent[j].mod.name);
  346.                 }
  347.                 blocked[this.adjacent[i].adjacent[j].mod.name] = true;
  348.             }
  349.         }
  350.     }
  351.     return blocked;
  352. }
  353.  
  354. Map.prototype.getFilteredModList = function() {
  355.     var blocked = this.getBlockedMods();
  356.  
  357.     return parsed.filter(function(mod) {
  358.         if (this.tier < mod.level || blocked[mod.name] || mod == this.mod) {
  359.             return false;
  360.         }
  361.         return true;
  362.     });
  363. }
  364.  
  365. Map.prototype.roll = function() {
  366.     var mods = this.getFilteredModList();
  367.  
  368.     var totalWeight = mods.reduce(function(acc, val) {
  369.         return acc + val.weights.default;
  370.     }, 0);
  371.     var roll = Math.random() * totalWeight;
  372.     var sum = 0;
  373.  
  374.     for (var mod in mods) {
  375.         sum += mods[mod].weights.default;
  376.         if (roll < sum) {
  377.             this.mod = mods[mod];
  378.             //console.log("Applied '" + this.mod.name + "' to " + this.name + ".");
  379.             return this.sextantCost;
  380.         }
  381.     }
  382. }
  383.  
  384. Map.prototype.isAdjacentTo = function(name) {
  385.     return Boolean(this.adjacent.find(map => map.name === name));
  386. }
  387.  
  388. // END Map prototype -------------------------------------------
  389.  
  390. // START atlas prototype ---------------------------------------
  391.  
  392. function Atlas(maps) {
  393.     this.maps = maps;
  394.     this.savedMods = {};
  395.  
  396.     for (var map in this.maps) {
  397.         this.savedMods[this.maps[map].name] = this.maps[map].mod;
  398.     }
  399.  
  400.     //console.log(this.savedMods);
  401. }
  402.  
  403. Atlas.prototype.reset = function() {
  404.     for (var map in this.savedMods) {
  405.         this.maps[map].mod = this.savedMods[map];
  406.     }
  407. };
  408.  
  409. // END atlas prototype -----------------------------------------
  410.  
  411. // create map objects
  412.  
  413. for (var map in mapData) {
  414.     new Map(map, mapData[map].tier, mapData[map].adjacent, mapData[map].mod);
  415. }
  416.  
  417. // objectify adjacent arrays
  418.  
  419. for (var k in maps) {
  420.     var map = maps[k];
  421.  
  422.     map.adjacent = map.adjacent.map(function(element) {
  423.         if (!maps[element]) {
  424.             throw new Error("Could not convert '" + element + "' to object");
  425.         }
  426.         return maps[element];
  427.     });
  428. }
  429.  
  430. // sanity check adjacents
  431.  
  432. for (var k in maps) {
  433.     var map = maps[k];
  434.  
  435.     map.adjacent.forEach(function(a) {
  436.         if (!a.isAdjacentTo(map.name)) {
  437.             throw new Error("1 sided adjacent relation: " + map.name + ", " + a.name);
  438.         }
  439.     })
  440. }
  441.  
  442. // block mods
  443.  
  444. function applyBlockMod(originMap, currentMap) {
  445.     if (currentMap.name == "Shaped Primordial Pool" || currentMap.isAdjacentTo("Shaped Primordial Pool")) {
  446.         return;
  447.     }
  448.     if (currentMap.mod) {
  449.         return;
  450.     }
  451.  
  452.     // filter out good mods
  453.     // filter non-white mods
  454.     var mods = originMap.getFilteredModList().filter(function(mod) {
  455.         return !goodMods[mod.name];
  456.     }).filter(function(mod) {
  457.         return mod.level == tier.WHITE;
  458.     });
  459.  
  460.     // sort by weight, descending
  461.     mods.sort(function(a, b) {
  462.         return b.weights.default-a.weights.default;
  463.     });
  464.  
  465.     currentMap.mod = mods[0];
  466.     console.log("Applied '" + currentMap.mod.name + "' to " + currentMap.name + ".");
  467. }
  468.  
  469. // First, apply sextants to maps 2 degrees away from Pool.
  470.  
  471. var m = maps["Shaped Primordial Pool"];
  472.  
  473. m.adjacent.forEach(function(map) {
  474.     map.adjacent.forEach(function(map2) {
  475.         applyBlockMod(m, map2);
  476.     });
  477. });
  478.  
  479. // Second, block sextants on Burial Chambers.
  480.  
  481. m = maps["Burial Chambers"];
  482.  
  483. m.adjacent.forEach(function(map) {
  484.     map.adjacent.forEach(function(map2) {
  485.         applyBlockMod(m, map2);
  486.     });
  487. });
  488.  
  489. for (var m in maps) {
  490.     var m = maps[m];
  491.  
  492.     if (!m.isAdjacentTo("Shaped Primordial Pool")) {
  493.         continue;
  494.     }
  495.  
  496.     // apply to adjacent maps
  497.  
  498.     for (var i = 0; i < m.adjacent.length; i++) {
  499.         var c = m.adjacent[i];
  500.         applyBlockMod(m, c);
  501.     }
  502.  
  503.     // apply to 2nd degree adjacent maps
  504.  
  505.     for (var i = 0; i < m.adjacent.length; i++) {
  506.         var proxy = m.adjacent[i];
  507.  
  508.         if (proxy.name == "Shaped Primordial Pool") {
  509.             continue;
  510.         }
  511.  
  512.         for (var j = 0; j < proxy.adjacent.length; j++) {
  513.             var c = proxy.adjacent[j];
  514.             applyBlockMod(m, c);
  515.         }
  516.     }
  517. }
  518.  
  519. // create atlas object and snapshot blocked mods
  520. var atl = new Atlas(maps);
  521.  
  522. // heaps permute --------------------------------------------
  523.  
  524. var swap = function(array, pos1, pos2) {
  525.     var temp = array[pos1];
  526.     array[pos1] = array[pos2];
  527.     array[pos2] = temp;
  528. };
  529.  
  530. var heapsPermute = function(array, output, n) {
  531.     n = n || array.length; // set n default to array.length
  532.     if (n === 1) {
  533.         output(array);
  534.     } else {
  535.         for (var i = 1; i <= n; i += 1) {
  536.             heapsPermute(array, output, n - 1);
  537.             if (n % 2) {
  538.                 var j = 1;
  539.             } else {
  540.                 var j = i;
  541.             }
  542.             swap(array, j - 1, n - 1); // -1 to account for javascript zero-indexing
  543.         }
  544.     }
  545. };
  546.  
  547. // END heaps permute -------------------------------------------
  548.  
  549. // START result prototype --------------------------------------
  550.  
  551. function result(order) {
  552.     this.order = order;
  553.     this.sum_x = 0;
  554.     this.sum_x2 = 0;
  555.     this.n = 0;
  556. }
  557.  
  558. result.prototype.mean = function() {
  559.     return this.sum_x / this.n;
  560. }
  561.  
  562. result.prototype.stdDev = function() {
  563.     var mean = this.mean();
  564.     return Math.sqrt(this.sum_x2 / this.n - mean * mean);
  565. }
  566.  
  567. result.prototype.generateSamples = function(n) {
  568.     // Apply sextants to maps
  569.     for (var iter = 0; iter < n; iter++) {
  570.         atl.reset();
  571.         var cost = 0;
  572.  
  573.         // First, roll any mod on each map in order.
  574.         this.order.forEach(function(m) {
  575.             if (!maps[m].mod) {
  576.                 cost += maps[m].roll();
  577.             }
  578.         });
  579.  
  580.         // Second, finish rolling each map to a good mod, again respecting the order.
  581.         this.order.forEach(function(m) {
  582.             // While no/bad sextant, keep rolling
  583.             while (!(maps[m].mod && goodMods[maps[m].mod.name])) {
  584.                 cost += maps[m].roll();
  585.             }
  586.         });
  587.  
  588.         this.sum_x += cost;
  589.         this.sum_x2 += cost * cost;
  590.         this.n++;
  591.     }
  592. }
  593.  
  594. result.prototype.confidenceInterval = function() {
  595.     return 1.645 * (this.stdDev() / Math.sqrt(this.n));
  596. }
  597.  
  598. // END result prototype ------------------------------------------
  599.  
  600. function countKeys(a) {
  601.     var n = 0;
  602.     for (var k in a) {
  603.         n++;
  604.     }
  605.     return n;
  606. }
  607.  
  608. var results = [];
  609.  
  610. var mapsToRoll = [];
  611. for (var map in maps) {
  612.     if (map == "Shaped Primordial Pool" || maps[map].isAdjacentTo("Shaped Primordial Pool")) {
  613.         console.log(map + " blocks " + countKeys(maps[map].getBlockedMods()) + " mods");
  614.         mapsToRoll.push(map);
  615.     }
  616. }
  617.  
  618. // create a result entry for every permutation
  619. heapsPermute(mapsToRoll, function(order) {
  620.     /*if ( order[0] !== "Shaped Primordial Pool" ) {
  621.     return;
  622.   }*/
  623.  
  624.     results.push(new result(order.slice(0)));
  625. });
  626.  
  627. while (true) {
  628.     var results_b = results.filter(function(r) {
  629.         if (r == results[0] || results[0].n == 0) {
  630.             return true;
  631.         }
  632.         return r.mean() - r.confidenceInterval() <= results[0].mean() + results[0].confidenceInterval();
  633.     });
  634.  
  635.     if (results_b.length <= 1 || results_b[0].n >= maxIterations) {
  636.         break;
  637.     }
  638.  
  639.     console.log(results[0].n + " iterations (" + results_b.length + " remaining permutations)");
  640.  
  641.     var iterTarget = results[0].n + 5000 / Math.sqrt(results_b.length);
  642.  
  643.     results_b.forEach(function(r) {
  644.         r.generateSamples(iterTarget - r.n);
  645.     });
  646.  
  647.     results.sort(function(a, b) {
  648.         return a.mean() - b.mean();
  649.     });
  650. }
  651.  
  652. console.log("Results (up to " + maxIterations + " iterations):");
  653.  
  654. for (var i = 0; i < results.length; i++) {
  655.     var str = "" + results[i].mean().toFixed(3) + " ± " + results[i].confidenceInterval().toFixed(3) + "c";
  656.  
  657.     for (var j = 0; j < results[i].order.length; j++) {
  658.         if (j > 0) {
  659.             str += ","
  660.         };
  661.         str += " " + results[i].order[j];
  662.     }
  663.  
  664.     console.log(str);
  665. }
Add Comment
Please, Sign In to add comment