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
20 Answers 20
MATL, (削除) 15 (削除ここまで) 13 bytes
t3$)&Gw&St3$)
Inputs u, then A.
Outputs B, then C without a separator, as there is no ambiguity.
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
Octave, 33 bytes
@(A,u){A(u,u) A([~,v]=sort(u),v)}
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.
Python 3 with numpy, (削除) 51 (削除ここまで) 45 bytes
lambda m,p:[m[x][:,x]for x in(p,p.argsort())]
-6 bytes thanks to @xnor
The function takes two arguments: a numpy matrix and a permutation vector having values from \0ドル\$ to \$n-1\$.
-
\$\begingroup\$ 45 bytes as lambda \$\endgroup\$xnor– xnor2019年09月21日 04:50:49 +00:00Commented 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– Joel2019年09月21日 04:55:40 +00:00Commented Sep 21, 2019 at 4:55
PowerShell, (削除) 78 (削除ここまで) (削除) 73 (削除ここまで) 71 bytes
($A,$u=$args)|%{$A[$u]|%{''+$_[$u]}
$u=1..$u.count|%{$u.indexof($_-1)}}
J, 19 bytes
(]/:~"1/:)"_ 1],:/:
- 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
/:~"1again 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.
- The right most
],:/: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.
-
\$\begingroup\$ Nice! I was thinking about applying sort+transpose twice, but will end up longer. \$\endgroup\$Galen Ivanov– Galen Ivanov2019年09月22日 07:32:31 +00:00Commented Sep 22, 2019 at 7:32
-
\$\begingroup\$
uis allowed to be 0-based, so sort (/:) could be indexing ({) with swapped args \$\endgroup\$ngn– ngn2019年09月22日 10:01:35 +00:00Commented Sep 22, 2019 at 10:01
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]]
-
\$\begingroup\$ It took me a minute to figure out what
vwas. 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\$Patrick Roberts– Patrick Roberts2019年09月23日 15:34:25 +00:00Commented Sep 23, 2019 at 15:34
APL (Dyalog Extended), 12 bytes SBCS
Full program. Prompts for \$u\$ and then \$A\$. Prints \$C\$ next to \$B\$, separated by two spaces
⌷∘⎕ ̈⍋ ̈⍛⍮⍨⍮⍨⎕
⎕ 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
-
1\$\begingroup\$ Nice! You can get down to 14 with
([{"1{)~(,:/:): Try it online! \$\endgroup\$Jonah– Jonah2019年09月22日 18:08:11 +00:00Commented 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– Jonah2019年09月22日 18:23:42 +00:00Commented 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– ngn2019年09月22日 18:54:34 +00:00Commented Sep 22, 2019 at 18:54
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
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(" "))}
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]
Perl 5, 79 bytes
sub{$[=1;($A,$u)=@_;@$v[@$u]=(1..@$u);map{$x=$_;[map[@$_[@$x]],@$A[@$x]]}$u,$v}
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].
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
q, 26 bytes
{Y:iasc y;(x[y;y];x[Y;Y])}
iasc returns indexes to sort it's argument.
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]]
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.
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))]]]
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.
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];}
Thanks to @ceilingcat suggestion to use #import <queue> instead of <vector> which mysteriously brings std::vector
-
\$\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– AZTECCO2019年12月10日 05:57:50 +00:00Commented Dec 10, 2019 at 5:57
-
1\$\begingroup\$ Tips for golfing in C++ \$\endgroup\$ceilingcat– ceilingcat2019年12月10日 09:59:48 +00:00Commented Dec 10, 2019 at 9:59
0as separator? \$\endgroup\$u = [2, 0, 1]? \$\endgroup\$