149 lines
4.3 KiB
Plaintext
149 lines
4.3 KiB
Plaintext
/* NetRexx */
|
|
options replace format comments java crossref symbols nobinary
|
|
|
|
import java.util.List
|
|
import java.util.ArrayList
|
|
|
|
-- =============================================================================
|
|
/**
|
|
* Permutation Iterator
|
|
* <br />
|
|
* <br />
|
|
* Algorithm by E. W. Dijkstra, "A Discipline of Programming", Prentice-Hall, 1976, p.71
|
|
*/
|
|
class RPermutationIterator implements Iterator
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
properties indirect
|
|
perms = List
|
|
permOrders = int[]
|
|
maxN
|
|
currentN
|
|
first = boolean
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
properties constant
|
|
isTrue = boolean (1 == 1)
|
|
isFalse = boolean (1 \= 1)
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method RPermutationIterator(initial = List) public
|
|
setUp(initial)
|
|
return
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method RPermutationIterator(initial = Object[]) public
|
|
init = ArrayList(initial.length)
|
|
loop elmt over initial
|
|
init.add(elmt)
|
|
end elmt
|
|
setUp(init)
|
|
return
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method RPermutationIterator(initial = Rexx[]) public
|
|
init = ArrayList(initial.length)
|
|
loop elmt over initial
|
|
init.add(elmt)
|
|
end elmt
|
|
setUp(init)
|
|
return
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method setUp(initial = List) private
|
|
setFirst(isTrue)
|
|
setPerms(initial)
|
|
setPermOrders(int[getPerms().size()])
|
|
setMaxN(getPermOrders().length)
|
|
setCurrentN(0)
|
|
po = getPermOrders()
|
|
loop i_ = 0 while i_ < po.length
|
|
po[i_] = i_
|
|
end i_
|
|
return
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method hasNext() public returns boolean
|
|
status = isTrue
|
|
if getCurrentN() == factorial(getMaxN()) then status = isFalse
|
|
setCurrentN(getCurrentN() + 1)
|
|
return status
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method next() public returns Object
|
|
if isFirst() then setFirst(isFalse)
|
|
else do
|
|
po = getPermOrders()
|
|
i_ = getMaxN() - 1
|
|
loop while po[i_ - 1] >= po[i_]
|
|
i_ = i_ - 1
|
|
end
|
|
|
|
j_ = getMaxN()
|
|
loop while po[j_ - 1] <= po[i_ - 1]
|
|
j_ = j_ - 1
|
|
end
|
|
|
|
swap(i_ - 1, j_ - 1)
|
|
|
|
i_ = i_ + 1
|
|
j_ = getMaxN()
|
|
loop while i_ < j_
|
|
swap(i_ - 1, j_ - 1)
|
|
i_ = i_ + 1
|
|
j_ = j_ - 1
|
|
end
|
|
end
|
|
return reorder()
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method remove() public signals UnsupportedOperationException
|
|
signal UnsupportedOperationException()
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method swap(i_, j_) private
|
|
po = getPermOrders()
|
|
save = po[i_]
|
|
po[i_] = po[j_]
|
|
po[j_] = save
|
|
return
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method reorder() private returns List
|
|
result = ArrayList(getPerms().size())
|
|
loop ix over getPermOrders()
|
|
result.add(getPerms().get(ix))
|
|
end ix
|
|
return result
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
/**
|
|
* Calculate n factorial: {@code n! = 1 * 2 * 3 .. * n}
|
|
* @param n
|
|
* @return n!
|
|
*/
|
|
method factorial(n) public static
|
|
fact = 1
|
|
if n > 1 then loop i = 1 while i <= n
|
|
fact = fact * i
|
|
end i
|
|
return fact
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
method main(args = String[]) public static
|
|
thing02 = RPermutationIterator(['alpha', 'omega'])
|
|
thing03 = RPermutationIterator([String 'one', 'two', 'three'])
|
|
thing04 = RPermutationIterator(Arrays.asList([Integer(1), Integer(2), Integer(3), Integer(4)]))
|
|
things = [thing02, thing03, thing04]
|
|
loop thing over things
|
|
N = thing.getMaxN()
|
|
say 'Permutations:' N'! =' factorial(N)
|
|
loop lineCount = 1 while thing.hasNext()
|
|
prm = thing.next()
|
|
say lineCount.right(8)':' prm.toString()
|
|
end lineCount
|
|
say 'Permutations:' N'! =' factorial(N)
|
|
say
|
|
end thing
|
|
return
|