user
For a given matrix, return the determinant and the permanent of the matrix.

The determinant is given by

:   :   det
        (
        A
        )
        =

        ∑

        σ
        sgn
        ⁡
        (
        σ
        )

        ∏

        i
        =
        1

        n

        M

        i
        ,

        σ

        i
        {\displaystyle {\displaystyle \det(A)=\sum \_{\sigma }\operatorname {sgn}(\sigma )\prod \_{i=1}^{n}M\_{i,\sigma \_{i}}}}

while the permanent is given by

:   :   perm
        ⁡
        (
        A
        )
        =

        ∑

        σ

        ∏

        i
        =
        1

        n

        M

        i
        ,

        σ

        i
        {\displaystyle {\displaystyle \operatorname {perm} (A)=\sum \_{\sigma }\prod \_{i=1}^{n}M\_{i,\sigma \_{i}}}}

In both cases the sum is over the permutations 

σ
{\displaystyle {\displaystyle \sigma }}
 of the permutations of 1, 2, ..., *n*. (A permutation's sign is 1 if there are an even number of inversions and -1 otherwise; see parity of a permutation.)

More efficient algorithms for the determinant are known: LU decomposition, see for example wp:LU decomposition#Computing the determinant. Efficient methods for calculating the permanent are not known.

Related task

* Permutations by swapping
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2015.12

Uses the permutations generator from the Permutations by swapping task. This implementation is naive and brute-force (slow) but exact.

```
sub insert ($x, @xs) { ([flat @xs[0 ..^ $_], $x, @xs[$_ .. *]] for 0 .. @xs) }
sub order ($sg, @xs) { $sg > 0 ?? @xs !! @xs.reverse }

multi σ_permutations ([]) { [] => 1 }

multi σ_permutations ([$x, *@xs]) {
    σ_permutations(@xs).map({ |order($_.value, insert($x, $_.key)) }) Z=> |(1,-1) xx *
}

sub m_arith ( @a, $op ) {
    note "Not a square matrix" and return
      if [||] map { @a.elems cmp @a[$_].elems }, ^@a;
    sum σ_permutations([^@a]).race.map: {
        my $permutation = .key;
        my $term = $op eq 'perm' ?? 1 !! .value;
        for $permutation.kv -> $i, $j { $term *= @a[$i][$j] };
        $term
    }
}

######### helper subs #########
sub hilbert-matrix (\h) {[(1..h).map(-> \n {[(n..^n+h).map: {(1/$_).FatRat}]})]}

sub rat-or-int ($num) {
    return $num unless $num ~~ Rat|FatRat;
    return $num.narrow if $num.narrow.WHAT ~~ Int;
    $num.nude.join: '/';
}

sub say-it ($message, @array) {
    my $max;
    @array.map: {$max max= max $_».&rat-or-int.comb(/\S+/)».chars};
    say "\n$message";
    $_».&rat-or-int.fmt(" %{$max}s").put for @array;
}

########### Testing ###########
my @tests = (
    [
        [ 1, 2 ],
        [ 3, 4 ]
    ],
    [
        [  1,  2,  3,  4 ],
        [  4,  5,  6,  7 ],
        [  7,  8,  9, 10 ],
        [ 10, 11, 12, 13 ]
    ],
    hilbert-matrix 7
);

for @tests -> @matrix {
    say-it 'Matrix:', @matrix;
    say "Determinant:\t", rat-or-int @matrix.&m_arith: <det>;
    say "Permanent:  \t", rat-or-int @matrix.&m_arith: <perm>;
    say '-' x 40;
}

```

**Output**

```
Matrix:
 1  2
 3  4
Determinant:	-2
Permanent:  	10
----------------------------------------

Matrix:
  1   2   3   4
  4   5   6   7
  7   8   9  10
 10  11  12  13
Determinant:	0
Permanent:  	29556
----------------------------------------

Matrix:
    1   1/2   1/3   1/4   1/5   1/6   1/7
  1/2   1/3   1/4   1/5   1/6   1/7   1/8
  1/3   1/4   1/5   1/6   1/7   1/8   1/9
  1/4   1/5   1/6   1/7   1/8   1/9  1/10
  1/5   1/6   1/7   1/8   1/9  1/10  1/11
  1/6   1/7   1/8   1/9  1/10  1/11  1/12
  1/7   1/8   1/9  1/10  1/11  1/12  1/13
Determinant:	1/2067909047925770649600000
Permanent:  	29453515169174062608487/2067909047925770649600000
----------------------------------------
```