Skip to content

Instantly share code, notes, and snippets.

@hijonathan
Last active February 14, 2023 15:14
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hijonathan/e597addcc327c9bd017c to your computer and use it in GitHub Desktop.
Save hijonathan/e597addcc327c9bd017c to your computer and use it in GitHub Desktop.
Javascript implementation of the largest remainder method http://en.wikipedia.org/wiki/Largest_remainder_method
values = [
13.626332
47.989636
9.596008
28.788024
]
# Round these percentage values into integers, ensuring that they equal 100% at the end.
roundedValues = getLargestRemainder values, 100
# [14, 48, 9, 29]
# Uses underscore.js, for brevity.
getLargestRemainder = (values, desiredSum) ->
sum = 0
parts = _.map values, (item, i) ->
# Get rounded down integer values.
int = item | 0
sum += int
return {
integer: int
decimal: item % 1
# Used to return values in original order.
originalIndex: i
}
if sum isnt desiredSum
# Sort in descending order.
parts = _(parts).sortBy('decimal').reverse()
diff = desiredSum - sum
i = 0
# Distribute additions.
while i < diff
parts[i].integer++
i++
return _.pluck _(parts).sortBy('originalIndex'), 'integer'
@geevb
Copy link

geevb commented Jul 24, 2021

Hey @djabif, I don't get much of coffee and your implementation really helped. Thanks!!

I just changed:

     valueParts = valueParts.sort(x => x.decimal);
     valueParts.sort(x => x.originalIndex)

to, respectively,

     valueParts = valueParts.sort((a, b) => b.decimal - a.decimal);
     valueParts.sort((a, b) => a.originalIndex - b.originalIndex)

as that is required to correctly sort the list by descending/ascending. Otherwise JS will just sort them alphabetically which can lead to errors.

@Lyokolux
Copy link

Lyokolux commented Feb 14, 2023

Hey @djabif, I don't get much of coffee and your implementation really helped. Thanks!!

I just changed:

     valueParts = valueParts.sort(x => x.decimal);
     valueParts.sort(x => x.originalIndex)

to, respectively,

     valueParts = valueParts.sort((a, b) => b.decimal - a.decimal);
     valueParts.sort((a, b) => a.originalIndex - b.originalIndex)

as that is required to correctly sort the list by descending/ascending. Otherwise JS will just sort them alphabetically which can lead to errors.

Thanks for your fix and for the gist @hijonathan.

FYI the values are different on Chrom/Firefox than in Safari without this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment