summary refs log blame commit diff stats
path: root/tests/iter/tpermutations.nim
blob: c5067ba31bb39978b3d16283430dceb52785199a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                                                                                                                            
 
                      























































                                                                             
discard """
output: '''
@[@[1.0, 2.0], @[3.0, 4.0]]
perm: 10.0 det: -2.0
@[@[1.0, 2.0, 3.0, 4.0], @[4.0, 5.0, 6.0, 7.0], @[7.0, 8.0, 9.0, 10.0], @[10.0, 11.0, 12.0, 13.0]]
perm: 29556.0 det: 0.0
@[@[0.0, 1.0, 2.0, 3.0, 4.0], @[5.0, 6.0, 7.0, 8.0, 9.0], @[10.0, 11.0, 12.0, 13.0, 14.0], @[15.0, 16.0, 17.0, 18.0, 19.0], @[20.0, 21.0, 22.0, 23.0, 24.0]]
perm: 6778800.0 det: 0.0
'''
"""


import sequtils, sugar

iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] =
  var
    d = 1
    c = newSeq[int](ys.len)
    xs = newSeq[T](ys.len)
    sign = 1

  for i, y in ys: xs[i] = y
  yield (xs, sign)

  block outter:
    while true:
      while d > 1:
        dec d
        c[d] = 0
      while c[d] >= d:
        inc d
        if d >= ys.len: break outter

      let i = if (d and 1) == 1: c[d] else: 0
      swap xs[i], xs[d]
      sign *= -1
      yield (xs, sign)
      inc c[d]

proc det(a: seq[seq[float]]): float =
  let n = toSeq 0..a.high
  for sigma, sign in n.permutations:
    result += sign.float * n.map((i: int) => a[i][sigma[i]]).foldl(a * b)

proc perm(a: seq[seq[float]]): float =
  let n = toSeq 0..a.high
  for sigma, sign in n.permutations:
    result += n.map((i: int) => a[i][sigma[i]]).foldl(a * b)

for a in [
    @[ @[1.0, 2.0]
     , @[3.0, 4.0]
    ],
    @[ @[ 1.0,  2,  3,  4]
     , @[ 4.0,  5,  6,  7]
     , @[ 7.0,  8,  9, 10]
     , @[10.0, 11, 12, 13]
    ],
    @[ @[ 0.0,  1,  2,  3,  4]
     , @[ 5.0,  6,  7,  8,  9]
     , @[10.0, 11, 12, 13, 14]
     , @[15.0, 16, 17, 18, 19]
     , @[20.0, 21, 22, 23, 24]
    ] ]:
  echo a
  echo "perm: ", a.perm, " det: ", a.det

# bug #3499 last snippet fixed
# bug 705  last snippet fixed