Skip to content
SelectricSimian edited this page Feb 20, 2013 · 1 revision

This module provides a simple permutations iterator which enumerates through a multi-dimensional range of numbers.

It is equivalent to nested for loops, and can be used in their place to avoid hard to read deeply nested code, or when the number of dimensions of the range is not known.

Each argument specifies a range for that dimension, which can be either a two-element table for the upper and lower bound in that dimension, or a single number. For the single number case, the number is used as the upper bound and the lower bound is assumed to be 1.

import wrap, yield from coroutine

export permutations = (first, ...)->
    first = {1, first} if 'number' == type first
    if ...
        rest = {...} -- ... is not inherited as an upvalue
        wrap ->
            for i = first[1], first[2]
                for sub in permutations unpack rest
                    yield {i, unpack sub}
    else
        wrap ->
            for i = first[1], first[2]
                yield {i}

example usage:

for permutation in permutations 3, 3, 3
    print unpack permutation

is equivalent to

for i = 1, 3
    for j = 1, 3
        for k = 1, 3
            print i, j, k

a more practical example:

-- count in binary
print "--- Count to 2^n - 1 in binary ---"
io.write "n: "
bits = io.read!
print "--- Counting up to #{2^bits - 1}, or #{'1'\rep bits} ---"
for permutation in permutations unpack (for i = 1, bits do {1, 0})
  print table.concat permutation
Clone this wiki locally