钻石化矩阵


20

给定一个矩阵,输出矩阵的表示形式,其中左上角元素在顶部,反对角线是中心行,右下角元素在底部。

例如,考虑以下矩阵:

1 2 3
4 5 6
7 8 9

此矩阵的菱形版本为:

  1
 4 2
7 5 3
 8 6
  9

输入和输出

输入矩阵将作为列表列表(或您选择的语言中的任何类似内容)给出。输出也应该是列表列表。

矩阵将仅包含正整数。

输入矩阵不一定是正方形。

输入矩阵将至少为1×1。

测试用例

Input:  [[1]]
Output: [[1]]

Input:  [[1,2],[3,4]]
Output: [[1],[3,2],[4]]

Input:  [[1,2,3],[4,5,6]]
Output: [[1],[4,2],[5,3],[6]]

Input:  [[11,2,5],[3,99,3],[4,8,15],[16,23,42]]
Output: [[11],[3,2],[4,99,5],[16,8,3],[23,15],[42]]

计分

这是,因此最短的答案以字节为单位。



相关/概括。(不过,这不会被认为是一个骗子,因为那允许数组不整齐并且需要旋转45度的倍数。)
Martin Ender 16'Apr

Answers:


19

J,7个字节

<@|./.

这是一个未命名的单子词动词,它采用矩阵并返回反对角线列表:

   input =. i.3 4
   input
0 1  2  3
4 5  6  7
8 9 10 11

   <@|./. input
┌─┬───┬─────┬─────┬────┬──┐
│0│4 1│8 5 2│9 6 3│10 7│11│
└─┴───┴─────┴─────┴────┴──┘

在这里测试。

说明

  • /.是J的内置函数,可将功能应用于每个反对角线。不幸的是,这些反对角线是按照我们想要的相反顺序给出的。
  • 在中<@|.,我们首先应用|.反转反对角线,然后<将其装箱(这是在J中返回一个参差不齐的数组的唯一方法,因为法线数组始终是矩形,所以反对角线将用零填充)。

那是疯狂而美丽。我有一天会花时间学习这种语言。
机器渴望

5

Python,91字节

e=enumerate
lambda M:[[r[n-i]for i,r in e(M)if-1<n-i<len(r)][::-1]for n,_ in e(M[1:]+M[0])]

Ideone上进行测试


Python + NumPy,69个字节

import numpy
lambda M:map(M[::-1].diagonal,range(1-len(M),len(M[0])))

期望将2D NumPy数组作为输入并返回NumPy数组的列表。在Ideone上进行测试


4

果冻,7个字节

ṚŒDṙZL$

在线尝试!

说明

Ṛ         Reverse the matrix vertically.
 ŒD       Get its diagonals. However these start from 
          the main diagonal, not the corners.
    ZL$   Get the width of the input matrix.
   ṙ      Rotate the list of diagonals left by that many 
          places to obtain the correct order.

不知道Jelly,但是如果它需要unicode操作数,则不是7个字节。
Guidobot

5
@Guidobot Jelly使用一个自定义代码页,它将其理解为一个字节的256个字符中的每一个编码。
丹尼斯

4

Mathematica,58 56个字节

a=Length;Reverse@#~Diagonal~b~Table~{b,1-a@#,a@#&@@#-1}&

匿名函数,采用嵌套数组。


您可以保存一个与Length[#]地方\[Transpose]。可能还有另一个别名Length
Sp3000

Length@#&@@#仅对于相同字节数的ASCII。
Martin Ender

3

CJam,17个字节

{eeSf.*::+W%zSf-}

一个未命名的块(函数),该块期望矩阵在堆栈上,并用其对角线替换。

在这里测试。

这(由Sp3000找到)适用于相同的字节数:

{_,,Sf*\.+W%zSf-}

说明

最好用一个例子来解释。考虑输入:

[[0  1  2  3]
 [4  5  6  7]
 [8  9 10 11]]

ee    e# Enumerate matrix, turning each row [x ... z] into [i [x ... z]] where
      e# i is the vertical index from the top.

[[0 [0  1  2  3]]
 [1 [4  5  6  7]]
 [2 [8  9 10 11]]]

Sf.*  e# Replace each i with a string of i spaces.

[[""   [0  1  2  3]]
 [" "  [4  5  6  7]]
 ["  " [8  9 10 11]]]

::+   e# Prepend these strings to the rows.

[[0  1  2  3]
 ['  4  5  6  7]
 ['  '  8  9 10 11]]   e# Note that each '  corresponds to a space character.

W%    e# Reverse the rows.

[['  '  8  9 10 11]
 ['  4  5  6  7]
 [0  1  2  3]]

z     e# Zip/transpose.

[[ '  '  0]
 [ '  4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

Sf-   e# Remove spaces from each row.

[[ 0]
 [ 4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

3

Python 2,88 87字节

lambda L:[filter(None,x)[::-1]for x in map(None,[],*[i*[0]+r for i,r in enumerate(L)])]

将0s开头,压缩,然后删除虚假元素。返回元组列表。这用于map(None,...)执行zip_longest (用填充空白点None)和filter(None,...)删除虚假元素。

烦人的是,我们需要在上添加额外的[]一行,map以确保返回元组列表,因为map(None,*[[1]])返回的[1]不是[(1,)]1x1矩阵。尽管多余的行被剥离了filter

(感谢@Dennis提供了-1个字节)


3

Ruby,68 66个字节

匿名函数。

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • 由于splat运算符的工作原理,通过放弃数组添加,我能够节省2个字节。

2

Mathematica,60个字节

#&@@@#&/@GatherBy[Join@@MapIndexed[List,#,{2}],Tr@*Last]&

其中是Mathematica读取的Unicode字符作为后缀\[Transpose]运算符。

这比其他Mathematica解决方案要长一些,但是我认为我会发布它,因为它不使用Diagonals内置方法,而是使用完全不同的方法。

说明

MapIndexed[List,#,{2}]

这首先会转置矩阵(如果将矩阵展平,则对角线会以正确的顺序出现)。然后,我们List将矩阵与索引一起映射到矩阵的单元格上,从而将每个矩阵元素i转换为{i, {x, y}}x并且y是矩阵中元素的坐标。

Join@@...

这使最外面的维度变平,因此我们现在具有按列优先顺序排列的矩阵元素的平坦列表(及其坐标)。

GatherBy[..., Tr@*Last]

这将这些元素按其坐标之和分组。请注意,对角线是constant的线x+y,因此这确实可以实现我们想要的分组。每个组内的顺序都将保留。现在我们只需要再次删除坐标即可。这是通过相当神秘的方式完成的:

#&@@@#&/@...

这将函数映射到#&@@@#&每个组,该函数本身适用 #&于组中的每个元素,并且#仅仅是第一个参数,即原始矩阵元素。


关于为什么解释\[transpose]
Fatalize 2016年

1
@Fatalize这是一个私人使用的Unicode代码点,与该代码点关联的标志符号Mathematica是上标Treference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]仅是该Unicode字符的ASCII音译。将Unicode字符或音译复制到Mathematica中将起作用。
Martin Ender

2

八度,77字节

稍微滥用一下accumarray功能:

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

这定义了一个匿名函数。要使用它,请分配给一个变量或使用ans

输入是带有:行分隔符的矩阵。输出是一个单元格数组,其中每行包含一个数组(八度等效于锯齿状数组)。这由Octave显示,显示了单元格数组的索引和每个单元格的内容。在这里尝试

要仅以空格和换行符显示结果:83个字节

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

您也可以在这里尝试


2

JavaScript(Firefox),86 75字节

a=>a.concat(a[0]).slice(1).map((_,i)=>[for(v of a)if(n=v[i--])n].reverse())

@Neil节省了11个字节!

在Firefox 30+中可以使用。接受一个数组数组。


不错的算法,但是您可以a.concat(a[0]).slice(1)用来获取正确长度的数组。另外,[for(of)]不是ES6;我通常将其写为(Firefox 30+)或类似的名称。
尼尔

@Neil Wow,我不了解使用concat和有点傻slice。谢谢!
user81655 '16

2

八度,63 62字节

感谢@DonMue ... @LuisMendo,删除了一个字节!

@(a)cellfun(@(x)x(x>0)',num2cell(spdiags(flipud(a)),1),'un',0)

我走了无聊的路线,对着对角线。

样品在亚乙基酮上运行。


我认为您可以缩短'uni''un'
Luis Mendo

@LuisMendo为什么,是的,我可以!谢谢!:)
烧杯

2

Haskell,83 82字节

r=zip[0..]
\o->fst$span(any(>0))[reverse[e|(x,t)<-r o,(v,e)<-r t,x+v==a]|a<-[0..]]

妮米保存了一个字节。谢谢!


1

Python,128个字节(numpy)

(lambda A: (lambda A,S:[[A[U][I-U] for U in range(min(S[1]-1,I),max(I-S[0]+1,0)-1,-1)] for I in range(S[1]+S[0]-1)])(A,A.shape))

欢迎来到编程难题和代码高尔夫球!默认情况下,提交高尔夫球挑战代码的提交必须是程序或函数,并且使用批准的I / O方法之一。不允许使用期望在硬编码变量中输入的代码段。
丹尼斯

看起来您可以将第一个使用的解决方案改写lambda为可以用作提交的lambda。
Alex A.

我将它LAMBDA
路易斯Masuelli

lambda A:[[A[U][I-U]for U in range(max(I-len(A)+1,0),min(len(A[0])-1,I)+1)]for I in range(len(A+A[0])-1)](与您的原始版本一样)会短一些。另外,您应该更改A[U][I-U]A[I-U][U]以从问题中获得方向。
丹尼斯

我回到家时会检查一下。很有道理
Luis Masuelli '16

1

Pyth41 17字节

tm_<dx+dYk.T+LaYk

在线尝试!

受到@Doorknob解决另一个问题的启发。

怎么运行的:

tm_<dx+dYk.T+LaYk
            +L      prepend to each subarray...
              aYk   (Y += ''). Y is initialized to [],
                    so this prepends [''] to the first
                    subarray, ['', ''] to the second, etc.
                    ['' 1  2  3
                     '' '' 4  5  6
                     '' '' '' 7  8  9
                     '' '' '' '' 10 11 12
                     '' '' '' '' '' 13 14 15]
          .T        transpose, giving us
                    ['' '' '' '' ''
                     1  '' '' '' ''
                     2  4  '' '' ''
                     3  5  7  '' ''
                     6  8  10 ''
                     9  11 13
                     12 14
                     15]
 m_<dx+dYk          removes all empty strings in the
                    subarrays while reversing each one
t                   remove the first subarray

先前尝试:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK

在线尝试!

怎么运行的:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK    input array stored as Q
JlQ                                          J = len(Q)
   KlhQ                                      K = len(Q[0])
       m                            Ut+JK    list for d from 0 to J+K-1:
        _m       }AAAAAAAAAABBBBBBBB             reversed list for k from A to B, where:
                  h.MZ,0-dtK                       A = max(0, d-(K-1))
                       0-dtK                               0  d-(K-1)
                            h.mb,tJd               B = min(J-1, d)
                                 tJd                       J-1  d
          @@Qk-dk                                    Q[k][d-k]

1

Groovy,77 73 75

{i->o=[].withDefault{[]};a=0;i.each{b=0;it.each{o[a+b++].add(0,it)};a++};o}

将数组数组作为输入并返回数组数组。

试试吧

编辑:我忘了输出anwser,添加后得分上升到75。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.