Skip to content

Instantly share code, notes, and snippets.

@xuyang2
Last active August 29, 2015 13:57
Show Gist options
  • Save xuyang2/9506707 to your computer and use it in GitHub Desktop.
Save xuyang2/9506707 to your computer and use it in GitHub Desktop.
Combination generator ported from Java
'use strict'
_ = require 'underscore'
# CombinationGenerator ported from Java.
# The algorithm is described by Kenneth H. Rosen, Discrete Mathematics and
# Its Applications, 2nd edition (NY: McGraw-Hill, 1991), pp. 284-286.
#
# Simple usage:
# combinations(["a", "b", "c", "d", "e"], 3)
# returns [["a","b","c"],["a","b","d"],["a","b","e"],["a","c","d"],["a","c","e"],["a","d","e"],["b","c","d"],["b","c","e"],["b","d","e"],["c","d","e"]]
#
class CombinationGenerator
constructor: (@n, @r) ->
@a = []
@numLeft = @total = calcTotal(@n, @r)
@reset()
reset: ->
@a = _.range(@r)
@numLeft = @total
getTotal: ->
@total
hasMore: ->
@numLeft > 0
getNext: ->
if (@numLeft == @total)
@numLeft--
return @a
i = @r - 1
while (@a[i] == @n - @r + i)
i--
@a[i]++
for j in [i + 1..@r - 1] by 1
@a[j] = @a[i] + j - i
@numLeft--
@a
# n! / (r! * (n-r)!)
calcTotal = (n, r) ->
total = 1
total = total * (n - r + i) / i for i in [1..r] by 1
total
# get all combinations
combinations = (arr, r) ->
arrarr = []
gen = new CombinationGenerator(arr.length, r)
while(gen.hasMore())
indices = gen.getNext()
arrarr.push _.map(indices, (i) ->
arr[i])
arrarr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment