18
\$\begingroup\$

For a 2 dimensional array we will call the elements in either the first row or the last column the "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] \$

Your task is to take as input a 2 dimensional array of positive integers, and repeatedly remove J-brackets from it until the remaining array has no more elements. Your output should be all the J-brackets removed in this process in the order they were removed.

The input will always be perfectly rectangular, and both dimensions will be at least 1. You may take input in any reasonable format.

This is so the goal is to minimize the size of your source code as measured in bytes.

Test cases

[[2]] -> [[2]]
[[1,2],[3,4]] -> [[1,2,4],[3]]
[[1,2,4,8],[9,3,6,7],[3,3,2,9]] -> [[1,2,4,8,7,9],[9,3,6,2],[3,3]]
[[1,2],[3,4],[5,6]] -> [[1,2,4,6], [3,5]]
[[1,2],[3,4],[5,6],[7,9]] -> [[1,2,4,6,9], [3,5,7]]
\$\endgroup\$
4
  • \$\begingroup\$ May we output additional trailing empty lists, as long as the first few lists are the correct output? \$\endgroup\$ Mar 29 at 11:32
  • \$\begingroup\$ @KevinCruijssen No you should only output correct results. \$\endgroup\$
    – Wheat Wizard
    Mar 29 at 11:32
  • \$\begingroup\$ Can the output be a one-dimensional list with each J-bracket separated by a non-integer number (like \$e\$ or \$\pi\$), or is that changing the output format too much? \$\endgroup\$
    – Aiden Chow
    Mar 29 at 23:18
  • \$\begingroup\$ Actually, can it be separated by 0 (not positive) as well? \$\endgroup\$
    – Aiden Chow
    Mar 29 at 23:31

19 Answers 19

5
\$\begingroup\$

Haskell, (53) 47 bytes

Fixed and golfed 6 bytes thanks to Wheat Wizard

f((a:b):c)=(a:b++(last<$>c)):f(init<$>c)
f x=[]

Try it online!

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

R, 37 bytes

\(m)split(m,pmin(row(m),rev(col(m))))

Attempt This Online!

Working on the related challenge led me to this approach. Test harness taken from pajonk's answer.

In an \$m\times n\$ matrix \$A\$, each element \$A_{ij}\$ is in the \$p^\text{th}\$ J-bracket if and only if \$\min(i,n+1-j)=p\$.

R has some odd built-ins that return the matrix \$R=\text{row}(M)\$ where \$R_{ij}=i\$ and similarly for \$C=\text{col}(M)\$. Reversing the column matrix luckily performs the right operation, and we take the parallel minimum of these matrices to obtain a matrix of J-brackets, which split helpfully breaks into groups of the right order.

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

BQN, 11 bytesSBCS

⌊⌜⟜⌽○↕´∘≢⊸⊔

Run online!

          ⊔  # Group the values by:
        ≢    # The shape of the matrix
      ´      # Reduce the shape by:
    ○↕       # Convert both integers to a range [0, n)
  ⟜⌽         # Reverse the right range
⌊⌜           # Minimum table
\$\endgroup\$
1
  • \$\begingroup\$ J translation not quite as nice: </.~&,(<./|.)&i./@$ \$\endgroup\$
    – Jonah
    Mar 29 at 13:33
4
\$\begingroup\$

R, 117 88 86 76 72 bytes

Edit: -29 31 bytes thanks to @Giuseppe; -10 bytes thanks to Robin Ryder; another -4 bytes thanks to @Giuseppe.

f=\(M)"if"(1%in%dim(t(M)),M,list(c(M[1,],M[-1,n<-ncol(M)]),f(M[-1,-n])))

Attempt This Online!

Recursive approach with some clever tricks by @Giuseppe and Robin Ryder.

\$\endgroup\$
8
  • \$\begingroup\$ You can save 10 bytes using negative indexing. I'd also suggest using m=t(M) to work around the [...,drop=T] behavior, with condition any(dim(m)<2). \$\endgroup\$
    – Giuseppe
    Mar 29 at 13:11
  • \$\begingroup\$ @Giuseppe, nice tricks, thanks! \$\endgroup\$
    – pajonk
    Mar 29 at 13:14
  • \$\begingroup\$ 86 bytes dunno how I missed that one. \$\endgroup\$
    – Giuseppe
    Mar 29 at 14:37
  • \$\begingroup\$ @Giuseppe, thanks again! \$\endgroup\$
    – pajonk
    Mar 29 at 16:42
  • 1
    \$\begingroup\$ @RobinRyder now you don't even need to alias m (maybe you never did) for 72 bytes \$\endgroup\$
    – Giuseppe
    Mar 29 at 19:18
3
\$\begingroup\$

Python 2, 52 bytes

a=input()
while[[]]<a:print a.pop(0)+map(list.pop,a)

Attempt This Online!

-4 bytes thanks to @ovs

\$\endgroup\$
3
  • \$\begingroup\$ map(list.pop,a) saves a byte (and 4 in Python 2) \$\endgroup\$
    – ovs
    Mar 29 at 10:40
  • \$\begingroup\$ This crashes on the last test case? \$\endgroup\$
    – Neil
    Mar 29 at 15:33
  • \$\begingroup\$ @Neil I know, it ends with an error on lists which are exactly twice as high as they are wide (e.g. [[1], [2]]). It still gives the right output though. \$\endgroup\$
    – pxeger
    Mar 29 at 16:22
3
\$\begingroup\$

Jelly, 10 bytes

ßest Friends Forever?!

Ḣ;Ṫ€W;ßFF?

A monadic Link that accepts a rectangular list of lists and yields a list of lists.

Try it online! Or see the test-suite.

How?

Ḣ;Ṫ€W;ßFF? - Link: list of lists, X
Ḣ          - head -> top row of X (mutates X)
   €       - for each of (the remaining rows of) X:
  Ṫ        -   tail -> last element of the row (mutates X)
 ;         - concatenate these together
    W      - wrap that list in a list -> Z
         ? - if...
        F  - ...condition: flatten (the mutated) X (falsey once empty or only empty rows)
      ß    - ...then: call this Link with (the mutated) X
       F   - ...else: flatten (the mutated) X -> an empty list
     ;     - Z concatenate that
\$\endgroup\$
3
\$\begingroup\$

K (ngn/k), 44 bytes

{,'/(&/d)#'(-1 1*!'d:#'1*:\x)_''1(1_'|+:)\x}

Try it online!

Solved in my worst attempt at find-the-j-twin. It seems a shame to let it go to waste...

\$\endgroup\$
3
+100
\$\begingroup\$

Vyxal, 16 bytes

λ[ḣƛt;J,:_ḢƛṪ;x¤

Try it Online!

Explanation

λ[ḣƛt;J,:_ḢƛṪ;x¤
λ                 Open a lambda (for recursion)
 [                If statement (check if truthy)
  ḣ               Separate the first item, push both sides to stack
   ƛt;            Map to last item of each
      J           Join both lists
       ,          Pop and print (the J bracket)
        :_        Duplicate and pop (seems pointless, but somehow makes it work right)
          Ḣ       All but the first item
           ƛṪ;    Map to all but the last item of each
              x   Recurse
               ¤  Empty space (so that it won't output an empty list at the end, since stack is implicitly output)

Definitely can be golfed down, but I'm bad at this.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You've unearthed some interesting and probably annoying bugs. We'll try to fix them lol \$\endgroup\$
    – emanresu A
    Apr 8 at 22:36
2
\$\begingroup\$

Python, 49 bytes

f=lambda a,i=0:a and[*a.pop(i),*f([*zip(*a)],~i)]

Attempt This Online!

Loosely based on @pxeger's Python 2 answer.

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

PARI/GP, 51 bytes

f(m)=m&&print(concat(m[1,],m[^1,#m]~))*f(m[^1,^#m])

Attempt This Online!

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

APL+WIN, 47 bytes

Prompts for 2 dimensional matrix

m←⎕⋄⍎∊(⌊/⍴m)⍴⊂'m[1;],1↓,m[;1↓⍴m]⋄m←1 0↓0 ¯1↓m⋄'

Try it online! Thanks to Dyalog APL Classic

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

05AB1E, 15 bytes

[ćs©€θ«,®€¨Wg_#

Try it online or verify all test cases.

Explanation:

[          # Loop indefinitely:
 ć         #  Extract head; pop and push first row and remainder-matrix
  s        #  Swap so the remainder-matrix is at the top
   ©       #  Store it in variable `®` (without popping)
    €θ     #  Pop and only leave the last value of each row
      «    #  Merge it to the extracted first row
       ,   #  Pop and output this list with trailing newline
   ®       #  Push matrix `®` again
    ۬     #  Remove the last integer from each row
      W    #  Push the flattened minimum of the matrix (without popping)
       g   #  Pop and push the length of it
        _  #  If this length is 0:
         # #   Stop the infinite list
\$\endgroup\$
1
\$\begingroup\$

Java 8, 109 bytes

m->{for(int i=0,j;;){var t=m[j=i++];for(;++j<m.length;)t.add(m[j].pop());if(t.size()>0)System.out.print(t);}}

Input as an array of Integer-Stacks; output prints directly to STDOUT.

Try it online.

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

Charcoal, 20 bytes

≔⮌AθW›θEθυI⟦⁺⊟θE⮌θ⊟κ

Try it online! Link is to verbose version of code. Explanation: Port of @pxeger's Python solution.

≔⮌Aθ

Reverse the input as Charcoal can only pop from the end of a list.

W›θEθυ

Repeat until the input has no rows or columns.

I⟦⁺⊟θE⮌θ⊟κ

Remove the now last row and the last column of the remaining rows reversed back into their original order and output those values.

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

Ruby, 46 bytes

f=->m{[m.shift+m.map(&:pop),*m*"">""?f[m]:[]]}

Try it online!

Takes advantage of shift and pop which modifies object in place and return what we needed.

Checking the updated m was a bit difficult because pop and shift may return nil which is truthy in Ruby

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

Factor, 69 bytes

[ [ 1 cut flip 1 short cut* rot prepend concat . flip ] until-empty ]

Try it online!

Explanation

It's a quotation (anonymous function) that takes a matrix as input and prints its J-brackets, one per line.

  • [ ... ] until-empty Repeatedly call a quotation on an input until it is empty.
         ! { { 1 2 4 8 } { 9 3 6 7 } { 3 3 2 9 } }
1 cut    ! { { 1 2 4 8 } } { { 9 3 6 7 } { 3 3 2 9 } }
flip     ! { { 1 2 4 8 } } { { 9 3 } { 3 3 } { 6 2 } { 7 9 } }
1 short  ! { { 1 2 4 8 } } { { 9 3 } { 3 3 } { 6 2 } { 7 9 } } 1
cut*     ! { { 1 2 4 8 } } { { 9 3 } { 3 3 } { 6 2 } } { { 7 9 } }
rot      ! { { 9 3 } { 3 3 } { 6 2 } } { { 7 9 } } { { 1 2 4 8 } }
prepend  ! { { 9 3 } { 3 3 } { 6 2 } } { { 1 2 4 8 } { 7 9 } }
concat   ! { { 9 3 } { 3 3 } { 6 2 } } { 1 2 4 8 7 9 }
.        ! { { 9 3 } { 3 3 } { 6 2 } }
flip     ! { { 9 3 6 } { 3 3 2 } }
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 91 bytes

(l=Length@#&@@#;Flatten@Pick[#,MapIndexed[Min[#,l-#2+1]&@@#2&,#,{2}],i]~Table~{i,Tr[1^#]})&

Try it online!

Feels too long but I couldn't find anything shorter

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

JavaScript (ES6),  66 63  59 bytes

Saved 4 bytes thank to @l4m2 (on both versions)

Returns a list.

f=m=>[[...m.shift(),...m.map(r=>r.pop())],...m>'0'?f(m):[]]

Try it online!

Commented

f =                // f is a recursive function taking
m =>               // a matrix m[]
[                  //
  [ ...m.shift(),  // extract the first row and split it
    ...m.map(r =>  // for each row r[] in m[]:
      r.pop()      //   extract the last element of r[]
    )              // end of map()
  ],               //
  ...m > '0' ?     // if there's still at least one number in m[]:
    f(m)           //   append the result of a recursive call
  :                // else:
    []             //   stop the recursion
]                  //

JavaScript (V8),  65 62  58 bytes

Prints the results.

f=m=>print([[m.shift()],...m].map(r=>r.pop()))|m>'0'&&f(m)

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ 59 \$\endgroup\$
    – l4m2
    Mar 29 at 18:33
  • \$\begingroup\$ maybe failed on [[1,2],[3,4],[5,6],[7,9],[1,2]] \$\endgroup\$
    – tsh
    Mar 30 at 9:08
  • 1
    \$\begingroup\$ Change ',' to '0' or any ascii 45 ~ 48 character should work. \$\endgroup\$
    – tsh
    Mar 30 at 9:40
0
\$\begingroup\$

PHP 5.4 (93 chars)

The function j take a $m PHP array and return the answer as a PHP array.

function j($m){for(;$k=array_shift($m);$j[]=$k)foreach($m as&$z)$k[]=array_pop($z);return$j;}

Variant using 105 characters :

The function j take a $m matrix and print the answer as JavaScript Object Notation array.

function j($m){for(;$k=array_shift($m);$j[]=$k)foreach($m as&$z)$k[]=array_pop($z);echo json_encode($j);}

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.