21
\$\begingroup\$

You are given a square \$n \times n\$ matrix \$A\$, and a list (or vector) \$u\$ of length \$n\$ containing the numbers \$1\$ through \$n\$ (or \$0\$ through \$n-1\$). Your task is to reorder the columns and rows of the matrix \$A\$ according to the order specified in \$u\$.

That is, you will construct a matrix \$B\$ where the \$(i,j)\$-th element is the \$(u(i),u(j))\$-th element of \$A\$. You should also output the inverse of this action; that is, the (i,j)-th element of \$A\$ will end up at position \$(u(i),u(j))\$ in a new matrix \$C\$.

For example, given $$A = \begin{bmatrix} 11 &12& 13 \\ 21& 22& 23 \\ 31& 32& 33 \end{bmatrix},\quad u=\begin{bmatrix}3 & 1 & 2\end{bmatrix}$$

the output should be $$B = \begin{bmatrix}33 & 31 & 32 \\ 13 & 11 & 12 \\ 23 & 21 & 22 \end{bmatrix},\quad C= \begin{bmatrix}22 & 23 & 21 \\32 & 33 & 31 \\ 12 & 13 & 11 \end{bmatrix}$$

You may take input and output through any of the default I/O methods. You do not have to specify which matrix is \$B\$ or \$C\$, as long as you output both. You may assume \$A\$ only contains positive integers, and you may use 1- or 0-based indexing for \$u\$. You must support matrices up to at least size \$64 \times 64\$.

Example

===== Input =====
A =
 35     1     6    26    19    24
  3    32     7    21    23    25
 31     9     2    22    27    20
  8    28    33    17    10    15
 30     5    34    12    14    16
  4    36    29    13    18    11
u=
  3 5 6 1 4 2

==== Output =====
B = 
  2    27    20    31    22     9
 34    14    16    30    12     5
 29    18    11     4    13    36
  6    19    24    35    26     1
 33    10    15     8    17    28
  7    23    25     3    21    32
C = 
 17    15     8    10    28    33
 13    11     4    18    36    29
 26    24    35    19     1     6
 12    16    30    14     5    34
 21    25     3    23    32     7
 22    20    31    27     9     2
\$\endgroup\$
5
  • \$\begingroup\$ Sandbox \$\endgroup\$
    – Sanchises
    Sep 20, 2019 at 20:01
  • \$\begingroup\$ Can we output without the empty line here, that is, like this? (there is no ambiguity) Or, failing that, use 0 as separator? \$\endgroup\$
    – Luis Mendo
    Sep 20, 2019 at 20:10
  • \$\begingroup\$ @LuisMendo Sure no problem. \$\endgroup\$
    – Sanchises
    Sep 20, 2019 at 20:32
  • \$\begingroup\$ Is 1-indexing required for this? Can we use 0-indexing and input u = [2, 0, 1]? \$\endgroup\$
    – Value Ink
    Sep 20, 2019 at 23:50
  • \$\begingroup\$ @ValueInk See the first sentence, [...] containing the numbers 1 through n (or 0 through n−1) \$\endgroup\$
    – Sanchises
    Sep 21, 2019 at 7:13

20 Answers 20

6
\$\begingroup\$

R, 42 bytes

function(A,o)list(A[o,o],A[I<-order(o),I])

Try it online!

Takes A as a matrix and 1-based indexes o.

\$\endgroup\$
6
\$\begingroup\$

MATL, 15 13 bytes

t3$)&Gw&St3$)

Inputs u, then A.

Outputs B, then C without a separator, as there is no ambiguity.

Try it online!

Explanation

t     % Take input u implicitly. Duplicate u
3$)   % Take input A implicitly. Index A with u as row and column indices
&G    % Push the two inputs again: u, A
w     % Swap
&S    % Push indices that would make u sorted. Call that v
t     % Duplicate v
3$)   % Index A with v as row as column indices. Display implcitly
\$\endgroup\$
5
\$\begingroup\$

Octave, 33 bytes

@(A,u){A(u,u) A([~,v]=sort(u),v)}

Try it online!

Thanks to Luis for correcting an error and saving several bytes!

Basic indexing works here for both tasks, by defining a vector \$ v \$ equal to the permutation that undoes \$ u \$. That is, if \$ u = ( 3, 1, 2 ) \$ then the first element of \$ v \$ is 2, since 1 is in the second position of \$ u \$. This is accomplished with Octave's sort function.

\$\endgroup\$
0
5
\$\begingroup\$

Python 3 with numpy, 51 45 bytes

lambda m,p:[m[x][:,x]for x in(p,p.argsort())]

Try it online!

-6 bytes thanks to @xnor

The function takes two arguments: a numpy matrix and a permutation vector having values from \$0\$ to \$n-1\$.

\$\endgroup\$
2
  • \$\begingroup\$ 45 bytes as lambda \$\endgroup\$
    – xnor
    Sep 21, 2019 at 4:50
  • \$\begingroup\$ @xnor Thanks ! I felt that it could be shortened in some way but the idea of using a for-loop did not come to my mind. \$\endgroup\$
    – Joel
    Sep 21, 2019 at 4:55
4
\$\begingroup\$

Wolfram Language (Mathematica), 30 bytes

ii[[#,#]]&/@{#,Ordering@#}&

Try it online!

Input as f[A][u].

\$\endgroup\$
4
\$\begingroup\$

PowerShell, 78 73 71 bytes

($A,$u=$args)|%{$A[$u]|%{''+$_[$u]}
$u=1..$u.count|%{$u.indexof($_-1)}}

Try it online.

\$\endgroup\$
3
\$\begingroup\$

Jelly, 13 bytes

ŒJṁ⁸ịⱮ⁹,Ụ¤œị⁸

Try it online!

\$\endgroup\$
3
\$\begingroup\$

J, 19 bytes

(]/:~"1/:)"_ 1],:/:

Try it online!

  • Main verb ]/:~"1/:
    • The right most /: sorts the left arg (matrix) according to the order that would sort the right arg (specified order). This sorts rows.
    • Now that result get sorted /:~"1 again according to the order specified ]. But this time we're sorting with rank 1, ie, we're sorting each row, which has the effect of sorting columns.
  • ],:/: We apply the above using both the order specified ] and the grade up of the order specified /:. This gives us the 2 results we want.
\$\endgroup\$
2
  • \$\begingroup\$ Nice! I was thinking about applying sort+transpose twice, but will end up longer. \$\endgroup\$ Sep 22, 2019 at 7:32
  • \$\begingroup\$ u is allowed to be 0-based, so sort (/:) could be indexing ({) with swapped args \$\endgroup\$
    – ngn
    Sep 22, 2019 at 10:01
3
\$\begingroup\$

JavaScript (Node.js), 77 70 68 bytes

a=>g=(u,v=[])=>[u.map((i,x)=>u.map(j=>a[i][j],v[i]=x)),v&&g(v,0)[0]]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ It took me a minute to figure out what v was. It's neat how you found a use for non-strict mode silent failure of property assignment to a primitive value, and used that for your recursion base-case. \$\endgroup\$ Sep 23, 2019 at 15:34
3
\$\begingroup\$

APL (Dyalog Extended), 12 bytesSBCS

Full program. Prompts for \$u\$ and then \$A\$. Prints \$C\$ next to \$B\$, separated by two spaces

⌷∘⎕¨⍋¨⍛⍮⍨⍮⍨⎕

Try it online!

 prompt for \$u\$; [3,1,2]

⍮⍨ juxtaposition-selfie; [[3,1,2],[3,1,2]]

⍋¨ permutation-inversion of each; [[2,3,1],[2,3,1]]
 then
⍮⍨ juxtapose with itself [[[2,3,1],[2,3,1]],[[3,1,2],[3,1,2]]]

 reorder
 the value of
\$A\$ as inputted
¨ using each pair as a set of orders, one order per axis

\$\endgroup\$
3
\$\begingroup\$

J, 17 16 15 14 bytes

-1 thanks to @Jonah

([{"1{)~(,:/:)

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice! You can get down to 14 with ([{"1{)~(,:/:): Try it online! \$\endgroup\$
    – Jonah
    Sep 22, 2019 at 18:08
  • \$\begingroup\$ Btw, random question: I noticed you golf (very well) in J, APL and K. Curious which you prefer overall? Also I seem to recall you saying you used K professionally, am I remembering that right? \$\endgroup\$
    – Jonah
    Sep 22, 2019 at 18:23
  • \$\begingroup\$ @Jonah if i must choose one, that would definitely be k (pls ping me in the k chat if you wanna know the reasons), but i do enjoy golfing in all array languages. sadly, i'm not one of the lucky few who can have a k-language job \$\endgroup\$
    – ngn
    Sep 22, 2019 at 18:54
2
\$\begingroup\$

Charcoal, 24 bytes

E⟦ηEη⌕ηκ⟧Eθ⪫Eθ§§θ§ιμ§ιξ 

Try it online! Link is to verbose version of code. 0-indexed. Note: Trailing space. Explanation:

    η                       Input `u`
   E                        Map over elements
     ⌕                      Index of
       κ                    Current index in
      η                     Input `u`
  η                         Input `u`
E⟦      ⟧                   Map over `u` and its inverse
          θ                 Input `A`
         E                  Map over elements
             θ              Input `A`
            E               Map over elements
                θ           Input `A`
               §            Indexed by
                  ι         Current vector
                 §          Indexed by
                   μ        Row index
              §             Indexed by
                     ι      Current vector
                    §       Indexed by
                      ξ     Column index
           ⪫                Join with spaces for readability
                            Implicitly print
\$\endgroup\$
2
\$\begingroup\$

Kotlin, 213 bytes

{a:List<List<Int>>,u:List<Int>->val s=u.size
for(l in List(s){r->List(s){c->a[u[r]][u[c]]}})println(l.joinToString(" "))
for(l in List(s){r->List(s){c->a[u.indexOf(r)][u.indexOf(c)]}})println(l.joinToString(" "))}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 21 bytes

Prompts for input of u followed by a. Outputs b immediately over the top of c with no separator:

(a←⎕)[u;u←⎕]⋄a[⍋u;⍋u]

Try it online! Courtesy of Dyalog Classic

\$\endgroup\$
1
\$\begingroup\$

Perl 5, 79 bytes

sub{$[=1;($A,$u)=@_;@$v[@$u]=(1..@$u);map{$x=$_;[map[@$_[@$x]],@$A[@$x]]}$u,$v}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Jelly,  12 11  13 bytes

+2 :( to fix cases when B = C

ṭþ`œị¥@Ƭị@2,0

A dyadic Link accepting a list of lists, A (n by n), on the left and a list of the first n integers on the right, u, which yields a list of lists of lists, [B, C].

Try it online!

How?

ṭþ`œị¥@Ƭị@2,0 - Link: A, u
       Ƭ      - collect up while the results are no longer unique, applying:
     ¥@       -   last two links as a dyad with swapped arguments:
  `           -     use left (u) as both arguments of:
 þ            -       outer product with:
ṭ             -         tack
   œị         -     multi-dimensional index into last result (starting with A)
                ...at the end of the Ƭ-loop we have [A,B,...,C]
                                                 or [A] if A=B=C
                                                 or [A,B] if B=C but A!=B
          2,0 - literal pair [2,0]
         @    - with swapped arguments:
        ị     -   index into (1-based & modular) -> [B,C]
                                                 or [A,A]=[B,C] if A=B=C
                                                 or [B,B]=[B,C] if B=C
\$\endgroup\$
1
\$\begingroup\$

q, 26 bytes

{Y:iasc y;(x[y;y];x[Y;Y])}

iasc returns indexes to sort it's argument.

\$\endgroup\$
1
\$\begingroup\$

Clean, 91 bytes

import StdEnv
$a u=map(\l={{a.[i,j]\\j<-l}\\i<-l})[u,[k\\i<-[0..]&_<-u,j<-u&k<-[0..]|j==i]]

Try it online!

Defines $ :: {{a}} [Int] -> [{{a}}] (used with a = Int) taking an array of arrays and a list of zero-based indices, returning a list of arrays of arrays containing B and C.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 91 bytes

lambda a,u:[[[a[y][x]for x in t]for y in t]for t in[u,[u.index(i)for i in range(len(u))]]]

Try it online!

Takes parameters as a 2D and 1D list and returns a list containing two 2D lists B and C. I'm not sure if there's a cleaner way to do all the for-loops.

\$\endgroup\$
1
\$\begingroup\$

C++ (gcc), 148 142 bytes

#import<queue>
#define q[o[i/z]*z+o[i%z]]
using V=std::vector<int>;int f(V m,V o,V&r,V&R,int z){int i=z*z;for(r=R=V(i);i--;r[i]=m q)R q=m[i];}

Try it online!

Thanks to @ceilingcat suggestion to use #import <queue> instead of <vector> which mysteriously brings std::vector

\$\endgroup\$
2
  • \$\begingroup\$ @ceilingcat now I see that import queue gives me access to vector.. Is it compiler dependant? I'm trying to search information about this but found nothing \$\endgroup\$
    – AZTECCO
    Dec 10, 2019 at 5:57
  • 1
    \$\begingroup\$ Tips for golfing in C++ \$\endgroup\$
    – ceilingcat
    Dec 10, 2019 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.