13
\$\begingroup\$

Take a non-nested array as input. Turn it into a matrix by using the following method:

Let's say my array is [1, 2, 3, 4, 5]

First, I repeat that array 5 times: (the length)

[[1, 2, 3, 4, 5],
 [1, 2, 3, 4, 5],
 [1, 2, 3, 4, 5],
 [1, 2, 3, 4, 5],
 [1, 2, 3, 4, 5]]

Then, I read it along the diagonals:

[[1],
 [2, 1],
 [3, 2, 1],
 [4, 3, 2, 1],
 [5, 4, 3, 2, 1],
 [5, 4, 3, 2],
 [5, 4, 3],
 [5, 4],
 [5]]

I flatten this array and split it into pieces of five (the length):

[[1, 2, 1, 3, 2],
 [1, 4, 3, 2, 1],
 [5, 4, 3, 2, 1],
 [5, 4, 3, 2, 5],
 [4, 3, 5, 4, 5]]

This is code golf. Fewest bytes wins.

\$\endgroup\$
  • \$\begingroup\$ Next time, please CAPITALIZE things. \$\endgroup\$ – Oliver Ni Nov 23 '16 at 20:18
  • \$\begingroup\$ How does this work if the original array has a length other than 5? \$\endgroup\$ – user62131 Nov 23 '16 at 20:18
  • \$\begingroup\$ @ais523 I'm assumming its the same thing, you just replace 'five' with the length \$\endgroup\$ – Oliver Ni Nov 23 '16 at 20:22
  • \$\begingroup\$ Can we assume the numbers always be positive integers? \$\endgroup\$ – Luis Mendo Nov 23 '16 at 20:30
  • 7
    \$\begingroup\$ @JohnCena You shouldn't accept the first answer, you need to give the post some time to gain traction and some more answers. \$\endgroup\$ – Kade Nov 23 '16 at 20:35

11 Answers 11

2
\$\begingroup\$

05AB1E, 13 bytes

.p¹.sR¦«í˜¹gä

Try it online!

Explanation:

                # Implicit input
 .p             # Get prefixes
   ¹            # Get first input
    .s          # Get suffixes
      R         # Reverse
       ¦        # Remove first element
        «       # Concatenate
         í      # Reverse every one
          ˜     # Flatten
           ¹gä  # Split into pieces of the length
                # Implicit print
\$\endgroup\$
  • \$\begingroup\$ don't you need to print it \$\endgroup\$ – user62265 Nov 23 '16 at 20:33
  • \$\begingroup\$ and how did you request input \$\endgroup\$ – user62265 Nov 23 '16 at 20:33
  • 1
    \$\begingroup\$ Many of these golfing languages, such as 05AB1E, have built in default rules for requesting input and producing output, so that the programmer doesn't have to waste bytes on them. \$\endgroup\$ – user62131 Nov 23 '16 at 20:35
  • 1
    \$\begingroup\$ The Output does not really match the desired output. It is no matrix and the numbers don't match. \$\endgroup\$ – Karl Napf Nov 23 '16 at 20:36
  • 1
    \$\begingroup\$ Well, it is a matrix, but the numbers are not correct (or tryitonline.net computes wrong) \$\endgroup\$ – Karl Napf Nov 23 '16 at 20:42
6
\$\begingroup\$

Jelly, 11 bytes

WẋLŒDUṙLFsL

Try it online!

Explanation

               Input: array z
WẋL            length(z) copies of z
   ŒD          Diagonals (starting with main diagonal)
     U         Reverse each
      ṙL       Rotate left length(z) places
               (now the top-left diagonal is in front)
        F      Flatten
         sL    Split into chunks of size length(z)
\$\endgroup\$
  • \$\begingroup\$ Hmm when I tried it with L it did weird stuff, hence I used the register :/ I just tried it again and it works... basically the same so I guess I shall just remove mine. \$\endgroup\$ – Jonathan Allan Nov 23 '16 at 21:37
  • 1
    \$\begingroup\$ Of course Jelly has "diagonals" built in.... :) \$\endgroup\$ – Greg Martin Nov 23 '16 at 22:59
3
\$\begingroup\$

Python 2, 105 96 bytes

-1 and -4 and -4 bytes thanks to Flp.Tkc

a=input()
n=len(a)
L,M=[],[]
for i in range(n):L+=a[i::-1];M+=a[:i:-1]
print zip(*[iter(L+M)]*n)

The for loop adds the items like in the description, the real magic happens in the zip which is from here

\$\endgroup\$
  • \$\begingroup\$ sorry for the spam, but now that R is only used once, you can just put it there directly :P \$\endgroup\$ – FlipTack Nov 23 '16 at 21:59
  • \$\begingroup\$ @Flp.Tkc no problem, i am happy :) \$\endgroup\$ – Karl Napf Nov 23 '16 at 22:00
3
\$\begingroup\$

JavaScript (ES6) 100 101 105

a=>eval("for(u=r=[],i=l=a.length;i+l;i--)for(j=l;j--;v&&((u%=l)||r.push(s=[]),s[u++]=v))v=a[j-i];r")

Less golfed

a => {
  u = 0
  for(r=[], i=l=a.length; i+l>0; i--)
    for(j=l; j--; )
    {
      v = a[j-i]
      if (v) 
      {
        u %= l
        if (u==0) r.push(s=[])
        s[u++] = v
      }
    }
  return r
}

Test

F=
a=>eval("for(u=r=[],i=l=a.length;i+l;i--)for(j=l;j--;v&&((u%=l)||r.push(s=[]),s[u++]=v))v=a[j-i];r")

function update() {
  var a=I.value.match(/\d+/g)
  if (a) {
    var r=F(a)
    O.textContent = r.join`\n`
  }
}

update()
<input id=I value='1 2 3 4 5' oninput='update()'>
<pre id=O></pre>

\$\endgroup\$
  • 1
    \$\begingroup\$ Wow, that's a very clever way to avoid the return. You should post a tip about that in the ES6 tip thread. \$\endgroup\$ – ETHproductions Nov 23 '16 at 22:07
  • \$\begingroup\$ @ETHproductions it has a very narrow scope. Most of times, eval is better. \$\endgroup\$ – edc65 Nov 24 '16 at 7:29
  • \$\begingroup\$ @ETHproductions indeed eval is better even this time :( \$\endgroup\$ – edc65 Nov 24 '16 at 7:48
  • \$\begingroup\$ @ETHproductions I posted the tip, even if it's rarely useful, just in case \$\endgroup\$ – edc65 Nov 28 '16 at 11:57
2
\$\begingroup\$

MATL, 17 bytes

!Gg*tRwZRhPXzGne!

Try it online!

How it works

The following explanation uses input [1 2 3 4 5] as an example. To visualize the intermediate results, insert % (comment symbol) after any statement in the code.

Note that ; is the row separator for matrices. So [1 2] is a row vector, [1; 2] is a column vector, and [1 0; 0 1] is the 2×2 identity matrix.

!     % Implicitly input a row vector. Transpose. Gives a column vector
      % STACK: [1; 2; 3; 4; 5]
Gg    % Push input with all (nonzero) values replaced by ones
      % STACK: [1; 2; 3; 4; 5], [1 1 1 1 1]
*     % Multiply, with broadcast. Gives a square matrix
      % STACK: [1 1 1 1 1;
                2 2 2 2 2;
                3 3 3 3 3;
                4 4 4 4 4;
                5 5 5 5 5]
tR    % Duplicate. Upper triangular part
      % STACK: [1 1 1 1 1;
                2 2 2 2 2;
                3 3 3 3 3;
                4 4 4 4 4;
                5 5 5 5 5],
               [1 1 1 1 1
                0 2 2 2 2;
                0 0 3 3 3;
                0 0 0 4 4;
                0 0 0 0 5]
wZR   % Swap. Lower triangular part, below main diagonal 
      % STACK: [1 1 1 1 1;
                0 2 2 2 2;
                0 0 3 3 3;
                0 0 0 4 4;
                0 0 0 0 5],
               [0 0 0 0 0;
                2 0 0 0 0;
                3 3 0 0 0;
                4 4 4 0 0;
                5 5 5 5 0]
h     % Concatenate horizontally
      % STACK: [1 1 1 1 1 0 0 0 0 0;
                0 2 2 2 2 2 0 0 0 0;
                0 0 3 3 3 3 3 0 0 0;
                0 0 0 4 4 4 4 4 0 0;
                0 0 0 0 5 5 5 5 5 0]
P     % Flip vertically
      % STACK: [0 0 0 0 5 5 5 5 5 0;
                0 0 0 4 4 4 4 4 0 0;
                0 0 3 3 3 3 3 0 0 0;
                0 2 2 2 2 2 0 0 0 0;
                1 1 1 1 1 0 0 0 0 0]
Xz    % Column vector of nonzeros, taken in column-major order
      % STACK: [1;2;1;3;2;1;4;3;2;1;5;4;3;2;1;5;4;3;2;5;4;3;5;4;5]
Gne   % Reshape into a matrix with as many rows as input size
      % STACK: [1 1 5 5 4;
                2 4 4 4 3;
                1 3 3 3 5;
                3 2 2 2 4;
                2 1 1 5 5]
 !    % Transpose. Implicitly display
      % STACK: [1 2 1 3 2;
                1 4 3 2 1;
                5 4 3 2 1;
                5 4 3 2 5;
                4 3 5 4 5]
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 116 bytes

a=>a.map(_=>b.splice(0,a.length),b=[].concat(...a.map((_,i)=>a.slice(~i)),...a.map((_,i)=>a.slice(0,~i))).reverse())

Well, it's a start...

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

R, 84 bytes

t(matrix(unlist(split(m<-t(matrix(rev(x<-scan()),l<-sum(1|x),l)),row(m)-col(m))),l))

Reads input from stdin and outputs/returns an R-matrix.

reversed_x <- rev(x<-scan())                # Read input from stdin and reverse
m <- t(matrix(reversed_x,l<-sum(1|x),l))    # Repeat and fit into matrix
diag_list <- split(m,row(m)-col(m))         # Split into ragged list of diagonals
t(matrix(unlist(diag_list),l))              # Flatten and transform back to matrix

Explained

The most interesting aspect about this answer is how the diagonals are retrieved. In general an object can be split up using the split function if supplied an object containing factors upon which the object is split into. To create these factors we can use col and row which return a matrix containing the column and row indices respectively. By taking the differences: row(m)-col(m) we get a matrix like:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0   -1   -2   -3   -4
[2,]    1    0   -1   -2   -3
[3,]    2    1    0   -1   -2
[4,]    3    2    1    0   -1
[5,]    4    3    2    1    0

in which each diagonal is uniquely identified. We can now split based on this matrix and turn it into a ragged list by applying split:

$`-4`
[1] 1
$`-3`
[1] 2 1 
$`-2`
[1] 3 2 1
$`-1`
[1] 4 3 2 1
$`0`
[1] 5 4 3 2 1
$`1`
[1] 5 4 3 2
$`2`
[1] 5 4 3
$`3`
[1] 5 4
$`4`
[1] 5

(Note how the name of each vector correspond to the diagonal values in the matrix above).

The last step is just to flatten and turn it into a matrix of the form:

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    1    3    2
[2,]    1    4    3    2    1
[3,]    5    4    3    2    1
[4,]    5    4    3    2    5
[5,]    4    3    5    4    5
\$\endgroup\$
0
\$\begingroup\$

Mathematica 93 Bytes

Partition[Flatten[Table[If[i>n,#[[n;;(i-n+1);;-1]],#[[i;;1;;-1]]],{i,1,2(n=Length@#)-1}]],n]&

Here's how I'd ordinarily write this code (109 Bytes):

Partition[Reverse@Flatten[Table[Reverse@Diagonal[ConstantArray[Reverse@#,n],k],{k,-(n=Length@#)+1,n-1}]],n]&

This matrix plot gives a good idea from the structure due to a sequentially increasing input vector.

enter image description here

Here's the matrix plot with a random input vector. Obviously some structure still exists.

enter image description here

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

Mathematica, 92 bytes

n=NestList[#2,(r=Reverse)@#,(l=Length@#)-1]&;{Most@r[#~n~Rest],#~n~Most}~ArrayReshape~{l,l}&

Unnamed function taking a list as its argument. There might be other structures to such a function, but hopefully I golfed this structure pretty good....

The first part n=NestList[#2,(r=Reverse)@#,(l=Length@#)-1]& defines a function n of two arguments: the first is a list of length l, and the second is a function to apply to lists. n applies that function l-1 times to the reversed argument list, saving all the results in its output list. (Defining r and l along the way is just golfing.)

n is called twice on the original list, once with the function being Rest (drop the first element of the list) and once with the function being Most (drop the last element). This produces all the desired sublists, but the whole list is there twice (hence the extra Most) and the first half is there in backwards order (hence the r[...]). Finally, ~ArrayReshape~{l,l} forgets the current list structure and forces it to be an lxl array.

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

Mathematica, 85 bytes

Literally performing the steps suggested:

(l=Length@#;Partition[Flatten@Table[Reverse@Diagonal[Table[#,l],i],{i,-l+1,l-1}],l])&

My gut says that there should be a clever way to use Part to do this shorter, but every attempt I've made has been longer than 85 bytes.

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

Ruby (110 bytes)

n=a.size
b=[*(0...n)]
b.product(b).group_by{|i,j|i+j}.flat_map{|_,f|f.sort.map{|i,j|a[i][j]}}.each_slice(n).to_a
  #=> [[1, 2, 1, 3, 2],
  #    [1, 4, 3, 2, 1],
  #    [5, 4, 3, 2, 1],
  #    [5, 4, 3, 2, 5],
  #    [4, 3, 5, 4, 5]]

The sort operation may not be required, but the doc for Enumerable#group_by does not guarantee the ordering of values in the hash values (which are arrays), but current versions of Ruby provide the ordering one would expect and the ordering I would need if sort were removed from my code.

The steps are as follows.

n=a.size 
  #=> 5 
b=[*(0...n)]
  #=> [0, 1, 2, 3, 4] 
c = b.product(b)
  #=> [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [1, 0], [1, 1], [1, 2], [1, 3],
  #    [1, 4], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [3, 0], [3, 1], [3, 2],
  #    [3, 3], [3, 4], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4]] 
d=c.group_by{|i,j|i+j}
  #=> {0=>[[0, 0]],
  #    1=>[[0, 1], [1, 0]],
  #    2=>[[0, 2], [1, 1], [2, 0]],
  #    3=>[[0, 3], [1, 2], [2, 1], [3, 0]],
  #    4=>[[0, 4], [1, 3], [2, 2], [3, 1], [4, 0]],
  #    5=>[[1, 4], [2, 3], [3, 2], [4, 1]],
  #    6=>[[2, 4], [3, 3], [4, 2]],
  #    7=>[[3, 4], [4, 3]],
  #    8=>[[4, 4]]} 
e=d.flat_map{|_,f|f.sort.map{|i,j|a[i][j]}}
  #=> [1, 2, 1, 3, 2, 1, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5] 
f=e.each_slice(n)
  #=> #<Enumerator: [1, 2, 1, 3, 2, 1, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2,
  #                  5, 4, 3, 5, 4, 5]:each_slice(5)>

Lastly, f.to_a returns the array shown earlier.

\$\endgroup\$

Your Answer

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