Created
May 30, 2019 10:52
-
-
Save halfninja/020e59a56f3b29d1fb9c158d3118a5da 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
/** Spread all items approximately equal between recipients. If there is a nonzero remainder N | |
* between the recipients, the first N recipients will receive an extra one each, so nobody will | |
* receive more than 1 than anyone else. | |
* | |
* Doesn't consider how many items a recipient may already be holding, so it won't seek to | |
* balance out recipients if they are currently unbalanced. | |
* | |
* @return Each recipient with a list of its allotted items | |
*/ | |
object distribute { | |
def apply[N, A](recipients: Seq[N], items: Seq[A]): Seq[(N, Seq[A])] = { | |
// We do .toList in a couple of places to handle where the incoming Seq is a Stream, | |
// which has confusing lazy properties especially with iterators. So don't remove them | |
// thinking you're all cool and great. | |
val itemsEach = if (recipients.isEmpty) 1 else Math.max(1, items.size / recipients.size) | |
val remainder = if (items.isEmpty) 0 else items.size % itemsEach | |
val iterator = items.toList.iterator | |
recipients.zipWithIndex.map { case (recipient, i) => | |
val count = if (i < remainder) itemsEach + 1 else itemsEach | |
(recipient, iterator.take(count).toList) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment