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
asked Sep 20, 2019 at 20:01
\$\endgroup\$
5
  • \$\begingroup\$ Sandbox \$\endgroup\$ Commented 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\$ Commented Sep 20, 2019 at 20:10
  • \$\begingroup\$ @LuisMendo Sure no problem. \$\endgroup\$ Commented 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\$ Commented Sep 20, 2019 at 23:50
  • \$\begingroup\$ @ValueInk See the first sentence, [...] containing the numbers 1 through n (or 0 through n−1) \$\endgroup\$ Commented 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.

answered Sep 21, 2019 at 0:00
\$\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
answered Sep 20, 2019 at 20:09
\$\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.

answered Sep 20, 2019 at 20:28
\$\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\$.

answered Sep 21, 2019 at 4:37
\$\endgroup\$
2
  • \$\begingroup\$ 45 bytes as lambda \$\endgroup\$ Commented 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\$ Commented Sep 21, 2019 at 4:55
4
\$\begingroup\$

Wolfram Language (Mathematica), 30 bytes

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

Try it online!

Input as f[A][u].

answered Sep 20, 2019 at 23:10
\$\endgroup\$
4
\$\begingroup\$

PowerShell, (削除) 78 (削除ここまで) (削除) 73 (削除ここまで) 71 bytes

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

Try it online.

answered Sep 21, 2019 at 17:04
\$\endgroup\$
3
\$\begingroup\$

Jelly, 13 bytes

ŒJṁ8ịⱮ9,Ụ¤œị8

Try it online!

answered Sep 20, 2019 at 23:38
\$\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.
answered Sep 21, 2019 at 4:26
\$\endgroup\$
2
  • \$\begingroup\$ Nice! I was thinking about applying sort+transpose twice, but will end up longer. \$\endgroup\$ Commented Sep 22, 2019 at 7:32
  • \$\begingroup\$ u is allowed to be 0-based, so sort (/:) could be indexing ({) with swapped args \$\endgroup\$ Commented 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!

answered Sep 22, 2019 at 11:00
\$\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\$ Commented Sep 23, 2019 at 15:34
3
\$\begingroup\$

APL (Dyalog Extended), 12 bytes SBCS

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

answered Sep 22, 2019 at 14:08
\$\endgroup\$
3
\$\begingroup\$

J, (削除) 17 16 15 (削除ここまで) 14 bytes

-1 thanks to @Jonah

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

Try it online!

answered Sep 22, 2019 at 9:31
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice! You can get down to 14 with ([{"1{)~(,:/:): Try it online! \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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
answered Sep 20, 2019 at 22:35
\$\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!

answered Sep 21, 2019 at 3:56
\$\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

answered Sep 22, 2019 at 10:38
\$\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!

answered Sep 21, 2019 at 7:14
\$\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
answered Sep 21, 2019 at 16:07
\$\endgroup\$
1
\$\begingroup\$

q, 26 bytes

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

iasc returns indexes to sort it's argument.

answered Sep 22, 2019 at 12:34
\$\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.

answered Sep 22, 2019 at 22:33
\$\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.

answered Sep 23, 2019 at 23:07
\$\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

answered Sep 22, 2019 at 8:57
\$\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\$ Commented Dec 10, 2019 at 5:57
  • 1
    \$\begingroup\$ Tips for golfing in C++ \$\endgroup\$ Commented Dec 10, 2019 at 9:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.