17
\$\begingroup\$

For a 2 dimensional array we will define the elements in either the first row or the last column to be the largest "J-Bracket" of the array. For example in the following array elements in the J-bracket are highlighted:

\$ \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} & \color{red}{\underline 8} \\ 9 & 3 & 6 & \color{red}{\underline 7} \\ 3 & 3 & 2 & \color{red}{\underline 9} \end{bmatrix} \$

The J-bracket is given in order starting from the first element of the first row and going clockwise. The element that is in both the row and the column is not repeated. So for the above that is:

\$ \left[1, 2, 4, 8, 7, 9\right] \$

To get the next largest J-bracket is just remove the largest J-bracket from the array and take the largest J-bracket of the remainder:

\$ \begin{bmatrix} \color{lightgrey}{1} & \color{lightgrey}{2} & \color{lightgrey}{4} & \color{lightgrey}{8} \\ \color{red}{\underline 9} & \color{red}{\underline 3} & \color{red}{\underline 6} & \color{lightgrey}{7} \\ 3 & 3 & \color{red}{\underline 2} & \color{lightgrey}{9} \end{bmatrix} \$

and so on until every element is in exactly 1 J-bracket.

The set of J-brackets from an array is not necessarily unique. In fact if the matrix is non-square every matrix has a twin with the same J-bracket set.

\$ \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} & \color{red}{\underline 8} \\ \color{green}9 & \color{green}3 & \color{green}6 & \color{red}{\underline 7} \\ \color{blue}{\overline 3} & \color{blue}{\overline 3} & \color{green}2 & \color{red}{\underline 9} \end{bmatrix} \cong \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} \\ \color{green}{9} & \color{green}3 & \color{red}{\underline 8} \\ \color{blue}{\overline 3} & \color{green}6 & \color{red}{\underline 7} \\ \color{blue}{\overline 3} & \color{green}2 & \color{red}{\underline 9} \end{bmatrix} \$

This twin has the opposite dimensions and in the case of a square matrix it is its own twin.

Your task is to take a 2D array of positive integers and output its J-twin. You may take input and output in any standard format but the input format should be the same as the output.

This is so answers will be scored in bytes with fewer bytes being the goal.

Test cases

[[2]] -> [[2]]
[[1,2,3]] -> [[1],[2],[3]]
[[1,2,4,8],[9,3,6,7],[3,3,2,9]] -> [[1,2,4],[9,3,8],[3,6,7],[3,2,9]]
[[1,2,4],[9,3,8],[3,6,7],[3,2,9]] -> [[1,2,4,8],[9,3,6,7],[3,3,2,9]]
\$\endgroup\$
2
  • \$\begingroup\$ Related \$\endgroup\$
    – Wheat Wizard
    Mar 30 at 13:06
  • 5
    \$\begingroup\$ Waiting for a J answer… \$\endgroup\$
    – Adám
    Mar 30 at 15:31

11 Answers 11

7
\$\begingroup\$

Jelly, 10 bytes

ZL_Lṙ@ŒdŒḍ

A monadic Link that accepts a rectangular list of lists and yields its J-bracket-twin as a list of lists.

Try it online! Or see the test-suite.

How?

ZL_Lṙ@ŒdŒḍ - Link: list of lists, A
Z          - transpose A
 L         - length of that -> columnCount(A)
   L       - length of A -> rowCount(A)
  _        - columnCount(A) subtract rowCount(A) = N
      Œd   - anti-diagonals of A
    ṙ@     - rotate this list of anti-diagonals left by N
        Œḍ - create a matrix with these anti-diagonals
\$\endgroup\$
5
\$\begingroup\$

K (ngn/k), 154 74 72 bytes

{$[1=&/#'1*:\x;:+x;[r:,/(*x),1_-1#'x;(,(#x)#r),+(+o(1_-1_'x)),,(#x)_r]]}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ This is basically two functions. One to make the J bracket and one to make a matrix from a J bracket. Looking at the other solutions, I clearly didn't need to make the J bracket first. I'm sure mimicking one of the other answers will be much shorter. \$\endgroup\$
    – doug
    Apr 3 at 10:29
  • \$\begingroup\$ Reworked to use recursion. \$\endgroup\$
    – doug
    Apr 3 at 12:00
4
\$\begingroup\$

Python 3, 111 bytes

def f(x):
 r,*a=x;k=len(a)
 if k*r[1:]:r+=map(list.pop,a);x=*zip(r[:k],*f(a)),r[k:]
 return[*map(list,zip(*x))]

Try it online!

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

R, 76 bytes

\(m)array(unsplit(split(m,i),rev(t(i<-pmin(row(m),rev(col(m)))))),dim(t(i)))

Attempt This Online!

As in the other challenge, splits the array to find the J-brackets. Then unsplits and adds array structure to get to the J-twin as a matrix.

Longer explanation to follow.

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

J, 62 60 bytes

Quite messy. The logic is very similar to my Python answer. Porting the Jelly answer might be shorter.

[:|:*@#@,(({.,{:"1@}.)((}.~#),~({.~#),.])|:@$:@:(}:"1)@}.^:)

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I wrote this a few days ago and forgot to post it. 51: Try it online! IIRC it didn't feel fully golfed yet. \$\endgroup\$
    – Jonah
    Apr 7 at 5:17
3
\$\begingroup\$

PARI/GP, 59 bytes

m->matrix(#m,#m~,i,j,m[i-d=min(l=i+j-1,#m)-min(l,#m~),j+d])

Attempt This Online!

Shift the \$n\$-th anti-diagonal to lower left by \$\min(n,w)-\min(n,h)\$, where \$w\$ and \$h\$ are the number of columns and rows of the matrix respectively.

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

Python + NumPy, 80 bytes

def f(a):b=0*a.T;b[1:,:-1]=a.any()and f(a[1:,:-1]);b[b<1]=a[a>0];a[:]=0;return b

Attempt This Online!

Accepts and destroys (overwrites with zeros) a NumPy array. Relies on elements being positive as promised in OP.

\$\endgroup\$
3
  • \$\begingroup\$ Shouldn't the import statement be included in the byte count? Or is there a precedence? \$\endgroup\$
    – jezza_99
    Apr 2 at 23:12
  • \$\begingroup\$ @jezza_99 right now I'm too lazy to find relevant meta post. But the consensus rule is import is only required if names from the module are actually referenced. Here I access the module's functionality exclusively through arguments and their attributes. Another way of looking at it would be that the function works without ever explicitly importing the module. \$\endgroup\$
    – loopy walt
    Apr 3 at 0:26
  • \$\begingroup\$ Ah yeah makes sense, just don't think I've seen an answer with that before. Cheers for the explanation \$\endgroup\$
    – jezza_99
    Apr 3 at 1:05
2
\$\begingroup\$

Haskell, 132 121 bytes

-11 thanks to Wheat Wizard

t[h]=pure<$>h
t s@([x]:r)=[s>>=id]
t(h:r)|n<-t$init<$>r,(a,b)<-splitAt(length r)$h++(last<$>r)=zipWith(\i->(++[i]))b(a:n)

Try it online!

If the input list has only one row, or only one column, transpose it. Otherwise, recurse on the "nub" that results from removing the J-bracket; then split the J-bracket into two parts, put one part atop the nub, and append the other part itemwise to the right side of the nub.

It's still pretty long, so I'm guessing there's a better way to do this...

\$\endgroup\$
2
  • \$\begingroup\$ 11 bytes shorter \$\endgroup\$
    – Wheat Wizard
    Apr 2 at 23:14
  • \$\begingroup\$ @WheatWizard Ah, thanks. I vaguely remembered that something like @ existed, but I'd forgotten the syntax. \$\endgroup\$
    – DLosc
    Apr 3 at 2:51
2
\$\begingroup\$

Charcoal, 52 43 39 bytes

F⁺θ§θ⁰⊞υ⟦⟧UMθEι⊞O§υ⁺κμλ≦⮌υIE§θ⁰Eθ⊟§υ⁺κμ

Try it online! Link is to verbose version of code. Outputs in Charcoal's default one-element-per-line format. Explanation:

F⁺θ§θ⁰⊞υ⟦⟧

Create a list of empty lists that will eventually hold the antidiagonals.

UMθEι⊞O§υ⁺κμλ

Extract the antidiagonals from the input. (This replaces each element in the array with the antidiagonal to which it belongs, but unfortunately I can't make use of this fact.)

≦⮌υ

Reverse the antidiagonals so that we can extract the elements in the original order using Pop().

IE§θ⁰Eθ⊟§υ⁺κμ`

Transpose the array, but read the elements back from the antidiagonals. (If Charcoal had an equivalent of JavaScript's unshift() then I would be able to unshift directly from the transposed array's antidiagonals to recover the elements.)

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

Haskell, 100 bytes

-3 bytes thanks to Wheat Wizard.

t m=[[m!!(i-1-x+y)!!(j+x-y)|j<-[0..l m-1],let[x,y]=min(i+j)<$>[l$m!!0,l m]]|i<-[1..l$m!!0]]
l=length

Try it online!

An ugly port of my PARI/GP answer.


Curry (PAKCS), 101 bytes

-4 bytes thanks to Wheat Wizard.

t m=[[m!!(i-1-x+y)!!(j+x-y)|j<-[0..l m-1],let[x,y]=map(min$i+j)[l$m!!0,l m]]|i<-[1..l$m!!0]]
l=length

Try it online!

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

Python3, 234 bytes:

E=enumerate
s=lambda m,d:(k for i,j in E(m)for x,k in E(j)if(i==d and x<(len(m[0])-d))or(i>d and x==(len(m[0])-1-d)))
r=lambda d,m:[[next(d[min(x,len(m)-1-y)])for y,_ in E(m)]for x,_ in E(m[0])]
lambda m:r({i:s(m,i)for i,_ in E(m)},m)

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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