import algorithm, sequtils iterator allPermutations*[T](x: seq[T]): seq[T] = # returns all permutations of a given seq. Order is wonky but we don't care. var workingCopy = x yield workingCopy while workingCopy.nextPermutation: # this mutates workingCopy yield workingCopy workingCopy = x while workingCopy.prevPermutation: yield workingCopy iterator allDigits*(lo, hi, size: Natural): seq[int] = if size > 0: # otherwise we get an infinite loop # we use uninitialized since we will initialize it below, but not necessarily with 0s var digits = newSeqUninitialized[int](size) for i in 0 .. digits.high: digits[i] = lo var complete = false while not complete: yield digits for i in countdown(digits.high, 0): if digits[i] < hi: inc digits[i] break elif i == 0: # since this is the last digit to be incremented, we must be done complete = true else: digits[i] = lo iterator possibleFutures*[C](dice: seq[C]): seq[tuple[color: C, value: int]] = # iterate over all possible sequences of die rolls. Each outcome # is returned as a 5-sequence of (color, number) tuples. for perm in dice.allPermutations: for d in allDigits(1, 3, dice.len): yield zip(perm, d)