Last active
September 5, 2019 22:13
-
-
Save dfkaye/29e28a2a1005704e59467417432203b3 to your computer and use it in GitHub Desktop.
See original Math Problem gist by @tevko at https://gist.github.com/tevko/20f8fc446d219f4714517aab19c5dd71
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 | |
// This version, 5 Sept 2019 | |
// First version, 18 Dec 2018 | |
// See original Math Problem gist by @tevko | |
// https://gist.github.com/tevko/20f8fc446d219f4714517aab19c5dd71 | |
// See postscript at the end of this gist for next thoughts... | |
// Set up our constraints first. | |
var count = 8; | |
var mintime = 45; | |
var budget = 600; | |
var remainder = budget; | |
/* | |
* First we have to allocate every task at least one pass, the minimum runtime | |
* and decrement that amount from the remainder. | |
*/ | |
var tasks = Array(count).fill(0).map(function(v, i) { | |
// decrement step | |
remainder -= mintime; | |
// allocation step | |
return { name: 'task_' + i, runtime: mintime }; | |
}); | |
// Verify that our remainder is correct | |
// 600 - (8 * 45) | |
// 600 - 360 | |
// Should be 240. | |
console.log({ remainder, passing: remainder === 240 }); | |
function getRandomIntInclusive(min, max) { | |
// The maximum is inclusive and the minimum is inclusive. | |
return Math.ceil(Math.random() * (max - min + 1) + 1); | |
} | |
// Procedural looping part. | |
var i = 0; | |
/* | |
* While there is time remaining to allocate, keep iterating the tasks, adding | |
* more time to each runtime. | |
* When the index reaches the number of tasks, reset it to 0 and start over. | |
* Stop iterating when remaining time is less than 1 second. | |
*/ | |
while (remainder > 0) { | |
if (i == count) { | |
i = 0; | |
} | |
var task = tasks[i++]; | |
var time = getRandomIntInclusive(task.runtime, remainder); | |
if (time > 0) { | |
/* | |
* Two reasons for this check: | |
* | |
* 1. The randomizing function can return a negative value once the | |
* remainder is sufficiently small. Subtracting negative time from | |
* the remainder increases it, resulting in an infinite loop. | |
* | |
* 2. If no positive time is returned, might as well skip to the next | |
* task rather than "perfecting" the current task. | |
*/ | |
console.log({ time, remainder }); | |
/* | |
* Increase the current task's runtime and decrement the remaining time to | |
* be allocated. | |
*/ | |
task.runtime += time; | |
remainder -= time; | |
if (remainder < 1) { | |
break; | |
} | |
} | |
} | |
// How'd we do? | |
var total = tasks.reduce(function(total, task) { | |
console.log(task); | |
return total + task.runtime; | |
}, 0); | |
console.log({ total }); | |
// Sample run. | |
/* | |
{ name: "task_0", runtime: 178 } | |
{ name: "task_1", runtime: 111 } | |
{ name: "task_2", runtime: 57 } | |
{ name: "task_3", runtime: 52 } | |
{ name: "task_4", runtime: 49 } | |
{ name: "task_5", runtime: 49 } | |
{ name: "task_6", runtime: 50 } | |
{ name: "task_7", runtime: 54 } | |
{ total: 600 } | |
*/ | |
/* | |
* Concluding Unscientific Postscript: | |
* | |
* I'm not sure the times are efficiently allocated. Given 2 more seconds, for | |
* example, in this test the first task could be run 4 times. As it is, there is | |
* a potential unusable allocation of 43 seconds that could applied to other | |
* tasks. | |
* | |
* On the other hand, we have no guarantee of task completion given even the 45- | |
* second minimum runtime. If we had a tolerance value for each task, say, task | |
* 0 takes no longer than 50 seconds, task 1 takes no longer than 100 seconds, | |
* etc., the tolerance ranges are 5 and 55 seconds, respectively. Knwoing *any* | |
* of those, we could reallocate runtime deltas more effectively. | |
*/ | |
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment