Created
May 25, 2016 07:33
-
-
Save ardeshireshghi/c2879b550e2ef4704c57bd6090e293da to your computer and use it in GitHub Desktop.
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
function inherits(constructor1, constructor2) { | |
constructor1.prototype = extend(constructor2.prototype); | |
} | |
function objectEmpty(obj) { | |
return Object.keys(obj).length === 0 && obj.constructor === Object; | |
} | |
function extend() { | |
var i = -1, | |
current, | |
newObject = {}; | |
if (!arguments) | |
return {}; | |
while (++i < arguments.length) { | |
var currentObj = arguments[i]; | |
for (var key in currentObj) { | |
if (currentObj.hasOwnProperty(key)) { | |
newObject[key] = currentObj[key]; | |
} | |
} | |
} | |
return newObject; | |
} | |
function Talk(attributes) { | |
this.attributes = {}; | |
this.setTitle(attributes.title); | |
this.setLength(attributes.length); | |
} | |
Talk.LIGHTNING_LENGTH = 'lightning'; | |
Talk.LIGHTNING_LENGTH_MIN = 5; | |
Talk.prototype = { | |
setTitle: function(title) { | |
this.attributes.title = title; | |
}, | |
setLength: function(length) { | |
this.attributes.length = (length === Talk.LIGHTNING_LENGTH) ? | |
Talk.LIGHTNING_LENGTH_MIN : length; | |
} | |
}; | |
function Collection(rawModelsData) { | |
if (rawModelsData) { | |
this.setModels(rawModelsData); | |
} | |
} | |
Collection.prototype = { | |
add: function(model) { | |
this.models.push((model instanceof this.model) ? model : new this.model(model)); | |
this.sort(); | |
}, | |
sort: function() { | |
var self = this; | |
return this.models; | |
this.models.sort(function(a, b){ | |
// console.log(a.attributes[self.sortBy], b.attributes[self.sortBy]);process.exit(); | |
return Math.sign(b.attributes[self.sortBy] - a.attributes[self.sortBy]); | |
}); | |
}, | |
setModels: function(rawModelsData) { | |
var self = this; | |
self.models = []; | |
rawModelsData.forEach(function(modelData) { | |
self.models.push(new self.model(modelData)); | |
}); | |
this.sort(); | |
} | |
} | |
function TalkCollection(talks) { | |
Collection.call(this, talks); | |
} | |
inherits(TalkCollection, Collection); | |
TalkCollection.prototype = extend(TalkCollection.prototype, { | |
model: Talk, | |
sortBy: 'length' | |
}); | |
var talksData = [ | |
{title: 'Writing Fast Tests Against Enterprise Rails ', length: 60}, | |
{title: 'Overdoing it in Python ', length: 45}, | |
{title: 'Lua for the Masses ', length: 30}, | |
{title: 'Ruby Errors from Mismatched Gem Versions ', length: 45}, | |
{title: 'Common Ruby Errors ', length: 45}, | |
{title: 'Rails for Python Developers' ,length: 'lightning'}, | |
{title: 'Communicating Over Distance ', length: 60}, | |
{title: 'Accounting-Driven Development ', length: 45}, | |
{title: 'Woah ', length: 30}, | |
{title: 'Sit Down and Write ', length: 30}, | |
{title: 'Pair Programming vs Noise ', length: 45}, | |
{title: 'Rails Magic ', length: 60}, | |
{title: 'Ruby on Rails: Why We Should Move On ', length: 60}, | |
{title: 'Clojure Ate Scala (on my project) ', length: 45}, | |
{title: 'Programming in the Boondocks of Seattle ', length: 30}, | |
{title: 'Ruby vs. Clojure for Back-End Development ', length: 30}, | |
{title: 'Ruby on Rails Legacy App Maintenance ', length: 60}, | |
{title: 'A World Without HackerNews ', length: 30}, | |
{title: 'User Interface CSS in Rails Apps ', length: 30} | |
]; | |
var talkCollection = new TalkCollection(talksData); | |
var sessions = { | |
morning: { | |
length: 180, | |
bucket: [], | |
bucketIndex: 0, | |
allocated: 0 | |
}, | |
afternoon: { | |
length: 240, | |
bucket: [], | |
bucketIndex: 0, | |
allocated: 0 | |
} | |
} | |
var sets = []; | |
// talkCollection.models.forEach(function(model) { | |
function inspect(data, selection, max, originalData) { | |
selection = selection || []; | |
originalData = originalData || data; | |
var getSum = function() { | |
var sum = 0; | |
selection.forEach(function(value) { | |
sum += value; | |
}); | |
return sum; | |
}; | |
if (data.length === 0) { | |
if (originalData.length > 1) { | |
return inspect(originalData.slice(1), undefined, max); | |
} else { | |
return selection; | |
} | |
} | |
if (getSum() + data[0] <= max) { | |
selection.push(data[0]); | |
console.log(selection); | |
if (getSum() === max) { | |
return selection; | |
} | |
} | |
return inspect(data.slice(1), selection, max, originalData); | |
} | |
function select(data, totalLength) { | |
var selection = []; | |
var getSum = function(array) { | |
var sum = 0; | |
array.forEach(function(value) { | |
sum += value; | |
}); | |
return sum; | |
}; | |
var min = function(array) { | |
return Math.min.apply(null, array); | |
} | |
// When there is no way we can select items which altogether are less than totalLength | |
// Or a totalLength which is smaller than our list's minimum!!! | |
if (getSum(data) < totalLength || min(data) >= totalLength) { | |
return []; | |
} | |
for (var i = 0; i < data.length; i++) { | |
selection = [ | |
data[i] | |
]; | |
// Quick selection (all resolved) | |
if (getSum(selection) === totalLength) { | |
return selection; | |
} | |
// There is no point in continuing (we have no selection) | |
if (i === data.length - 1) { | |
break; | |
} | |
var dataCopy = data.slice(i); | |
var j = 1; | |
while (dataCopy.length >= 2) { | |
// Add the item if the sum does not exceed the max | |
if ((getSum(selection) + dataCopy[j]) <= totalLength) { | |
selection.push(dataCopy[j]); | |
// Happy happy | |
if (getSum(selection) === totalLength) { | |
return selection; | |
} | |
} | |
// we skip values which make the sum greater than totalLength | |
// Oops! Got to the end of data copy not yet resolved the selection | |
if (j >= dataCopy.length - 1) { | |
// Removing the last selected item from data copy and selection | |
dataCopy.splice(selection.length - 1, 1) | |
selection.pop(); | |
// Bring the index back to adjecent item after last selection | |
j = selection.length - 1; | |
} | |
j++; | |
} | |
} | |
return []; | |
} | |
select([60,60,40,30,70,100,50], 180) | |
Array.prototype.remove = function(items) { | |
var t = this; | |
items.forEach(function(item){ | |
(t.indexOf(item) > -1) && t.splice(t.indexOf(item), 1); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment