Last active
August 29, 2015 14:06
-
-
Save trylks/10ba4e798cad26510008 to your computer and use it in GitHub Desktop.
Programming kata suggested by a friend, formulation not available at this moment.
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
def allocate(amount, weights): | |
total = sum(weights) | |
for weight in weights: | |
assign = round(weight * amount / total) if total else 0 | |
yield assign | |
amount -= assign | |
total -= weight | |
if __name__ == "__main__": | |
for testCase in [(10, [4,4,1]), (1, [2,4,1]), (1000, [34,4,12])]: | |
print(list(allocate(*testCase))) |
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
package main | |
import collection.JavaConversions._ | |
object Allocator { | |
def main(args: Array[String]) { | |
val intargs = args.map(_.toInt) | |
println(allocate(intargs(0), intargs.slice(1, intargs.size).toVector)) | |
} | |
// Intermediate results | |
case class IR(val weight: Int, val assigned: Int, val originalOrder: Int, val unfairness: Double) | |
def allocate(amount: Int, weights: Vector[Int]): Vector[Int] = { | |
val proportion = amount.toDouble / weights.sum | |
val firstApproximation = weights | |
.zip(1 to weights.length) | |
.map { case (weight, order) => makeIR(weight, proportion, order) } | |
val missing = amount - firstApproximation.map(_.assigned).sum | |
// patch and return | |
firstApproximation | |
.sortBy(-_.unfairness) | |
.zip(Vector.fill(missing)(1) ++ Vector.fill(weights.length - missing)(0)) | |
.map { case (ir, inc) => ir.copy(assigned = ir.assigned + inc) } | |
.sortBy(_.originalOrder) | |
.map(_.assigned) | |
} | |
def makeIR(weight: Int, proportion: Double, originalOrder: Int): IR = { | |
val thefloor = math.floor(weight * proportion).toInt | |
IR(weight, thefloor, originalOrder, weight * proportion - thefloor) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment