tpermutations.nim 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import sequtils, sugar
  2. iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] =
  3. var
  4. d = 1
  5. c = newSeq[int](ys.len)
  6. xs = newSeq[T](ys.len)
  7. sign = 1
  8. for i, y in ys: xs[i] = y
  9. yield (xs, sign)
  10. block outter:
  11. while true:
  12. while d > 1:
  13. dec d
  14. c[d] = 0
  15. while c[d] >= d:
  16. inc d
  17. if d >= ys.len: break outter
  18. let i = if (d and 1) == 1: c[d] else: 0
  19. swap xs[i], xs[d]
  20. sign *= -1
  21. yield (xs, sign)
  22. inc c[d]
  23. proc det(a: seq[seq[float]]): float =
  24. let n = toSeq 0..a.high
  25. for sigma, sign in n.permutations:
  26. result += sign.float * n.map((i: int) => a[i][sigma[i]]).foldl(a * b)
  27. proc perm(a: seq[seq[float]]): float =
  28. let n = toSeq 0..a.high
  29. for sigma, sign in n.permutations:
  30. result += n.map((i: int) => a[i][sigma[i]]).foldl(a * b)
  31. for a in [
  32. @[ @[1.0, 2.0]
  33. , @[3.0, 4.0]
  34. ],
  35. @[ @[ 1.0, 2, 3, 4]
  36. , @[ 4.0, 5, 6, 7]
  37. , @[ 7.0, 8, 9, 10]
  38. , @[10.0, 11, 12, 13]
  39. ],
  40. @[ @[ 0.0, 1, 2, 3, 4]
  41. , @[ 5.0, 6, 7, 8, 9]
  42. , @[10.0, 11, 12, 13, 14]
  43. , @[15.0, 16, 17, 18, 19]
  44. , @[20.0, 21, 22, 23, 24]
  45. ] ]:
  46. echo a
  47. echo "perm: ", a.perm, " det: ", a.det
  48. # bug #3499 last snippet fixed
  49. # bug 705 last snippet fixed