1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
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
|