Transposes and Diagonals

21

1

For this challenge, you should write a program or function which outputs the diagonals of a given square matrix. However, if you transpose the rows and columns of your solution's source code, it should instead become a program or function which returns the matrix's antidiagonals. Read on for specifics...

Rules

  • The source code of your solution is considered as a 2D grid of characters, separated by a standard newline of your choice (linefeed, carriage return, or a combination of both).
  • No line in your source code may be longer than the previous one. Here are some examples of valid layouts:

    ###
    ###
    ###
    

    ########
    #######
    ###
    ###
    #
    

    And here is an example of an invalid layout (as the third line is longer than the second):

    ######
    ####
    #####
    ###
    
  • Your two solutions should be each others' transpose, that is you should obtain one from the other by swapping rows and columns. Here are two valid pairs:

    abc
    def
    ghi
    

    adg
    beh
    cfi
    

    And

    print 10
    (~^_^)~
    foo
    bar
    !
    

    p(fb!
    r~oa
    i^or
    n_
    t^
     )
    1~
    0
    

    Note that spaces are treated like any other characters. In particular, trailing spaces are significant as they might not be trailing spaces in the transpose.

  • Each solution should be a program or function which takes a non-empty square matrix of single-digit integers as input. One solution should output a list of all diagonals of the matrix and the other should output a list of all antidiagonals. You may use any reasonable, unambiguous input and output formats, but they must be identical between the two solutions (this also means they either have to be both functions or both programs).

  • Each diagonal runs from the top left to the bottom right, and they should be ordered from top to bottom.
  • Each antidiagonal runs from the bottom left to the top right, and they should be ordered from top to bottom.

Scoring

To encourage solutions that are as "square" as possible, the primary score is the number of rows or the number of columns of your solution, whichever is larger. Less is better. Ties are broken by the number of characters in the solution, not counting the newlines. Again, less is better. Example:

abcd
efg
h

This and its transpose would have a primary score of 4 (as there are 4 columns) and a tie-breaking score of 8 (as there are 8 non-newline characters). Please cite both values in the header of your answer.

Test Cases

The actual task performed by the two solutions shouldn't be the primary challenge here, but here are two examples to help you test your solutions:

Input:
1 2 3
4 5 6
7 8 9
Diagonals:
3
2 6
1 5 9
4 8
7
Antidiagonals:
1
4 2
7 5 3
8 6
9

Input:
1 0 1 0
0 1 0 1
1 0 1 0
0 1 0 1
Diagonals:
0
1 1
0 0 0 
1 1 1 1
0 0 0
1 1
0
Antidiagonals:
1
0 0
1 1 1
0 0 0 0
1 1 1
0 0
1

Martin Ender

Posted 2017-07-01T09:06:40.867

Reputation: 184 808

Related. – Martin Ender – 2017-07-01T09:07:03.757

As I realized the sandbox post was by you before getting halfway through it, before I got on SE this morning I realized you had already posted this... at this point I'm starting to think I must be psychic :P – ETHproductions – 2017-07-01T15:54:06.780

Answers

19

Javascript, score 20 14, (258 176 non-newline characters)

///mmm()mu[=+r
///=.av=a,pr"=
///> p,>px=[ [
m=>//(yv()xp"]
m. ////.(=+]+)
map((////>y?u&
v,y)=>v//r]r:&
.map((u,x//[ur
)=>r[p=m.//p)
length-1-//],
x+y]=r[p]////
?r[p]+" "+u//
:u),r=[])&&r

and

///mmmv.)lx?:
///=.a,m=e+ru
///> pya>ny[)
m=>//()prg]p,
m. //(=([t=]r
map(//>(phr+=
(v,y//vu=-["[
)=>v.//,m1p ]
map((//x.-]")
u,x)=>r////+&
[p=x+y]////u&
=r[p]?r[p]//r
+" "+u:u),//
r=[])&&r

Example code snippet:

f=

///mmm()mu[=+r
///=.av=a,pr"=
///> p,>px=[ [
m=>//(yv()xp"]
m. ////.(=+]+)
map((////>y?u&
v,y)=>v//r]r:&
.map((u,x//[ur
)=>r[p=m.//p)
length-1-//],
x+y]=r[p]////
?r[p]+" "+u//
:u),r=[])&&r

console.log(f([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]))

and

f=

///mmmv.)lx?:
///=.a,m=e+ru
///> pya>ny[)
m=>//()prg]p,
m. //(=([t=]r
map(//>(phr+=
(v,y//vu=-["[
)=>v.//,m1p ]
map((//x.-]")
u,x)=>r////+&
[p=x+y]////u&
=r[p]?r[p]//r
+" "+u:u),//
r=[])&&r

console.log(f([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]))

Herman L

Posted 2017-07-01T09:06:40.867

Reputation: 3 611

Can you enable syntax highlighting? Place <!-- language-all: lang-javascript --> before the first code block. – CalculatorFeline – 2017-07-02T16:12:59.863

8

MATL, score 10 (100 non-newline characters)

%P!       
  Q&%     
  TXd!    
  %d      
     P!   
      "@% 
       Xz 
      %z  
         q
         !

There are 10 lines of 10 characters (note the trailing spaces).

The above code produces the diagonals. Try it online!

The transposed version produces the anti-diagonals. Try it online!

Explanation

Note that

  • % is a comment symbol, which causes the rest of the line to be ignored.

  • Two-char functions like Xd cannot be split into an X and a d in consecutive lines.

Original code

The original code, linearized and without the commented part, is

Q&TXd!P!"@Xzq!

which works as follows:

Q      % Implicit input. Add 1 to each entry to make them positive
&      % This modifes default inputs/ouputs of next function, which is Xd
       % Specifically, it specifies 2 inputs and 1 ouput
T      % Push true
Xd     % Diagonals of matrix. With second input true, it gives all diagonals,
       % starting from below. The columns are arranged as columns of a matrix,
       % padding with zeros
!P!    % Flip horizontally. This is to produce the correct display order
"      % For each column
  @    %   Push current column
  Xz   %   Remove zeros
  q    %   Subtract 1
  !    %   Transpose into a row
       % Implicit end. Implicit display of stack contents

Transposed code

The transposed code, linearized, is

P!QT&Xd!P!"@Xzq!

which has the following two differences compared to the original code:

  • T and & are swapped. This has no effect, because T is a literal, not a function, so it doesn't intercept the & specification.
  • P! is added at the begining.

The added code modifies the input matrix so that the diagonals of the modified matrix are the anti-diagonals of the input:

P      % Implicit input. Flip vertically
!      % Transpose

Luis Mendo

Posted 2017-07-01T09:06:40.867

Reputation: 87 464

7

Jelly, Score 7, 49 non-newline bytes

Diagonal printing program

......U
......Œ
......D
......ṙ
......L
......Ṛ
ŒDṙLṚUU

Try it online!

Anti-diagonal-printing Program

......Œ
......D
......ṙ
......L
......Ṛ
......U  
UŒDṙLṚU

Try it online!

Older Answer(Unordered Output), Score 3, 6 non-newline bytes

Diagonal-printing program

UU
UŒ
ŒD

Try it online!

Anti-diagonal printing program

UUŒ
UŒD

Try it online!

officialaimm

Posted 2017-07-01T09:06:40.867

Reputation: 2 739

6

Jelly, score 4 (12 characters)

previous scores: 5 (16 characters), 4 (16 characters)

Original

ŒDṙṚ
D  ñ
ṙLñL

Try it online!

Transpose

ŒDṙ
D L
ṙ ñ
ṚñL

Try it online!

Background

Diagonals

The straightforward way of obtaining the diagonals (topmost to bottommost) of a square matrix is as follows.

ŒDṙLṚ

For an input matrix M, ŒD lists M's diagonals, starting with the main diagonal and moving upwards.

For the input

1 2 3
4 5 6
7 8 9

this yields

1 5 9
2 6
3
7
4 8

ṙL then computes M‘s length with L and rotates the result length(M) units to the left.

For our example, the length is 3 and we get

7
4 8
1 5 9
2 6
3

Finally, reverses the order of the diagonals, returning

3
2 6
1 5 9
4 8
7

for our example input.

Anti-diagonals

The same building blocks can be used to obtain the anti-diagonals (again, topmost to bottommost) of a square matrix.

ṚŒDṙL

For an input matrix M, first reverses the order of the rows.

For the input

1 2 3
4 5 6
7 8 9

this yields

7 8 9
4 5 6
1 2 3

As before, ŒDṙL generates the diagonals (bottommost to topmost) of the result.

For our example, this returns

1
4 2
7 5 3
8 6
9

as desired.

How it works

In Jelly, each line defines a link (function). In particular, the last line defines the main link, which is executed when the program starts.

Other links must be called. This answer uses ñ, which executes the link below dyadically. ñ wraps around, so when it is called from the main link, it executes the link on the first line.

Original

The main link

ṙLñL

takes an input matrix M, computes its length with L, then rotates the input length(M) units to the left with (note that this doesn't alter M), and finally calls the first link with the result (M) and length(M) as arguments.

The first link

ŒDṙṚ

computes the diagonals of M with ŒD (as seen in the previous section), rotates the result length(M) units to the left with , then reverses the order of the result with .

The second link is never called.

Transpose

The main link

 ṚñL

takes an input matrix M and computes its reverse with . It then computes the length of M with L and calls the first link with arguments reverse(M) and length(M).

The first link

ŒDṙ

then computes the diagonals of reverse(M) with ŒD (as seen in the previous section), and finally rotates the result length(M) units to the left with .

The remaining links are never called.

Dennis

Posted 2017-07-01T09:06:40.867

Reputation: 196 637

5

R, score 14 13 11 (99 95 non-newline characters)

Thanks to @Giuseppe for improving the score by 1. Shaved off a few characters by making use of redundancies in the transpositions. Currently the best score for a non-golfing language!

######`,scr
`::`(#:fpoo
pryr,#:)llw
f)(###`(i((
split (#tmm
p,col(p#())
)+row#r#m-)
(p)))#y#,#)
######r

And transposed:

#`pfsp)(#
#:r)p,+p#
#:y(lcr)#
#`r#ioo)#
#(,#tlw)#
#### (###
`::`(pryr
,f)(####
split(m,
col(m)-#
row(m)))

Try it online!

rturnbull

Posted 2017-07-01T09:06:40.867

Reputation: 3 689

1row(m)+col(m) is shorter for the anti-diagonals. – Giuseppe – 2018-01-04T22:39:18.730

@Giuseppe Of course, thanks! Edited now. – rturnbull – 2018-01-04T22:54:26.113

4

Husk, 7 9 4 characters, score 4 3

∂T
m
↔

Try it online!

-4 characters thanks to BMO.

Erik the Outgolfer

Posted 2017-07-01T09:06:40.867

Reputation: 38 134