字形矩阵


43

作为其压缩算法的一部分,JPEG标准沿着交替方向的对角线将矩阵展开为向量:

在此处输入图片说明

您的任务是获取矩阵(不一定是正方形)并以展开形式返回。举个例子:

[1 2 3 4
 5 6 7 8
 9 1 2 3]

应该屈服

[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]

规则

您可以假设矩阵元素是小于的正整数10

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行参数或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

输入矩阵可以任何方便,明确,嵌套的列表或字符串格式给出,也可以与两个矩阵维一起作为平面列表给出。(或者,当然,如果您的语言包含矩阵类型,则作为矩阵类型。)

输出向量可以是任何方便,明确,平坦的列表或字符串格式。

适用标准规则。

测试用例

[[1]]                                               => [1]
[[1 2] [3 1]]                                       => [1 2 3 1]
[[1 2 3 1]]                                         => [1 2 3 1]
[[1 2 3] [5 6 4] [9 7 8] [1 2 3]]                   => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 3 4] [5 6 7 8] [9 1 2 3]]                     => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 6 3 1 2] [5 9 4 7 8 3]]                       => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 5 9 6 3 4 7 1 2 8 3]]                         => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1] [2] [5] [9] [6] [3] [4] [7] [1] [2] [8] [3]]   => [1 2 5 9 6 3 4 7 1 2 8 3]

相关挑战


1
输入可以是J中的实际矩阵吗?还是需要将其从嵌套列表转换为矩阵作为函数的一部分?
加雷斯

4
如果我们将矩阵作为2D数组,是否仍可以将维度作为输入?
xnor

1
@Gareth是的,您可以将矩阵类型作为输入。
马丁·恩德

1
@xnor嗯,有点棘手。我觉得将大量冗余信息用于预处理输入。
马丁·恩德

如果这是语言的本机顺序,则平面列表可以按列优先顺序排列吗?
Luis Mendo

Answers:


27

J,31 30 14 12 11字节

[:;<@|.`</.

是的。太大。

将矩阵作为输入。

说明

J在这里有优势。有一个称为oblique/.)的命令,该命令依次采用斜线并将动词应用于它们。在这种情况下,我使用动名词来交替应用两个动词:<box)和<@|.reverse和box)。然后,只需使用;raze)将所有内容拆箱即可。


26
J是使我感到需要高级英语才能理解的唯一语言。
亚历克斯A.

2
@AlexA。顺便说一句,“命令”一词应该是“副词”。
亚当

11

Pyth,24 23 21 20 19 18 17字节

ssm_W=!Td.T+LaYkQ

备用17字节版本: ssuL_G=!T.T+LaYkQ

                Q  input
           +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  1  2  3]
         .T        transpose, giving us
                   ['' '' ''
                    1  '' ''
                    2  5  ''
                    3  6  9
                    4  7  1
                    8  2
                    3]
  m_W=!Td          black magic
 s                 join subarrays together
s                  join *everything* on empty string (which means ''s used for
                     padding disappear)

感谢@FryAmTheEggman一个字节,@ Jakube两个字节和@isaacg一个字节!

上面提到的“黑魔法”的解释:m_W=!Td本质上颠倒了所有其他子数组。它通过映射_W=!T每个子数组来实现。W是有条件的应用程序,因此它_(反转)所有子数组,其中=!Ttrue。T是一个预初始化为十(真实)的变量,=!T表示(T = !T)。因此,它切换了以true开头并返回新值的变量的值,这意味着它将在返回falsy,truey,falsy,truey之间交替。

测试套件在这里


11

Jelly,24 19 15 13 11个字节

pS€żị"¥pỤị⁵

将行数,列数和平面列表作为单独的命令行参数。

在线尝试!

这个怎么运作

pS€żị"¥pỤị⁵  Main link. Argument: m (rows), n (columns), A (list, flat)

p            Compute the Cartesian product [1, ..., m] × [1, ..., n]. This yields
             the indices of the matrix M, i.e., [[1, 1], [1, 2], ..., [m, n]].
 S€          Compute the sums of all index pairs.
       p     Yield the Cartesian product.
      ¥      Dyadic chain. Arguments: Sums, Cartesian product.
    ị"       For each index pair in the Cartesian product, retrieve the coordinate
             at the index of its sum, i.e., map [i, j] to i if i + j is odd and to
             j if i + j is even.
   ż         Zip the sums with the retrieved indices.
       Ụ     Sort [1, ..., mn] by the corresponding item in the resulting list.
        ị⁵   Retrieve the corresponding items from A.

sk 我不确定现在是否可以缩短我的时间。:-S
Gareth

并不是说我不会尝试...
Gareth

为什么果冻还没有继承Oblique?我建议的APL字形?也许是斯堪的纳维亚øǿ
亚当

7

MATL28 27字节

tZyZ}:w:!+-1y^7MGn/*-X:K#S)

从我的回答改编这里。一般的想法是创建一个与输入大小相同的2D数组,并填充值以与之字形路径相同的顺序增加。然后对该数组的线性化(展平)版本进行排序,并保留该排序的索引。这些是为了产生锯齿形路径而需要应用于输入的索引。

输入形式为

[1 2 3; 5 6 4; 9 7 8; 1 2 3]

说明

在线尝试!

t       % input 2D array. Duplicate
ZyZ}    % get size as length-2 vector. Split into two numbers: r, c
:       % range [1,2,...,c] as a row vector
w:!     % swap, range [1;2;...;r] as a column vector
+       % add with broadcast. Gives a 2D array
-1      % push -1
y^      % duplicate previous 2D array. Compute -1 raised to that
7M      % push [1;2;...;r] again
Gn/     % divide by input matrix size, that is, r*c
*       % multiply
-       % subtract
X:      % linearize 2D array into column array
K#S     % sort and push the indices of the sorting. Gives a column vector
)       % index input matrix with that column vector

4

Matlab,134个字节

我只是尽力缩短Matlab中的代码,就像电报一样。

function V=z(M)
[m,n]=size(M);
a=(1:m)'*ones(1,n);
b=ones(m,1)*(1:n);
A=a+b-1;
B=a-b;
C=(A.^2+(-1).^A.*B+1);
[~,I]=sort(C(:));
V=M(:);
V=V(I)';

笔记:

  1. M是一个m×n矩阵。
  2. ab都是大小相同的矩阵M,的每一行均由a等于其行号的数字组成,而的每一列b均等于其列号。因此,a+ b是一个矩阵,其元素等于其行号和列号的和,即matrix(p,q)=p+q
  3. 因此,A(p,q)=p+q-1; 和B(p,q)=p-q
  4. C在数学上表示为以下等式。 字形递增矩阵 通过该方程式,可以使之字形增加的矩阵如下所示。
C =
     1     2     6     7
     3     5     8    14
     4     9    13    18
    10    12    19    25
  1. C表示锯齿状结果中M元素的顺序。然后,[~,I]=sort(C(:));返回顺序,即I,因此V=V(I)'是结果。

是的,我刚刚找到它,现在我对其进行了更新。
Guoyang Qin

@AlexA。谢谢亚历克斯。因为我是新手,所以我希望将其尽可能短地缩短,但是要使其简短。现在,我已经修复了代码。
Guoyang Qin

看起来不错。不错的第一篇文章!:)
Alex A.

3

JavaScript(SpiderMonkey 30 +),99个字节

x=>[for(y of[...x,...x[0]].keys())for(z of Array(y+1).keys())if(a=x[y%2?z:y-z])if(b=a[y%2?y-z:z])b]

在Firefox 44中进行了测试。将输入作为2D数组。


3

Python 2,84字节

lambda N,w,h:[N[i*w+s-i]for s in range(w+h+1)for i in range(h)[::s%2*2-1]if-1<s-i<w]

达妮米的答案。采取具有给定宽度和高度的平面阵列。xsot保存了一个字节。


88个字节:

lambda M,w,h:[M[i]for i in sorted(range(w*h),key=lambda i:(i/w+i%w,-i*(-1)**(i/w+i%w)))]

采取具有给定宽度和高度的平面阵列。(i/w,i%w)根据行加列是奇数还是偶数,以升序之和的锯齿顺序对相应的2D坐标进行排序,以得到对角线,并通过增加或减小行值将其平分。


如果条件可以进一步缩短。
xsot

@xsot不错。
xnor

3

Haskell,79 78 73字节

(m#h)w=[m!!(y*w+x-y)|x<-[0..h+w],y<-g!!x$[0..x],y<h,x-y<w]
g=reverse:id:g

输入是带有行和列数的平面列表,例如( [1,2,6,3,1,2,5,9,4,7,8,3] # 2) 6-> [1,2,5,9,6,3,4,7,1,2,8,3]

工作原理:在两个嵌套循环中遍历矩阵(h行,w列)的x和y坐标:

  | 0 1 2 3 4 5 6 7 8    outer loop               Index is y*w+x-y, i.e.
--+------------------    x from 0 to h+w          the elements are accessed
0 | 1 2 6 3 1 2                                   in the following order:
1 | 5 9 4 7 8 3
2 |                                               1 2 4 6  8 10 
3 |                                               3 5 7 9 11 12
4 |
5 |
6 |
7 | inner loop:
8 | y from 0 to x

即从上/右到下/左,跳出绑定索引(y并且x必须满足y<hx-y<w)。当x为偶数时,内循环的顺序相反:yx转到0。我通过为y范围([0..x]即的xth元素)选择一个修改函数来做到这一点[reverse,id,reverse,id,...]

编辑:@xnor重新排列循环并保存5个字节。谢谢!


我认为你可以做到g=id:reverse:g
xnor

(y-x)*w可以通过转置问题来减少多阳离子上的括号:(m#h)w=[m!!(x*w+y-x)|y<-[0..h+w],x<-g!!y$[0..y],x<h,y-x<w] g=reverse:id:g。转换成Python可以节省3个字符。
xnor

1

Python 2 + NumPy,122个字节

我承认。我努力了。不幸的是,无法轻松修改此相同方法来解决其他两个相关挑战...

import numpy
def f(m):w=len(m);print sum([list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))],[])

将一个numpy数组作为输入。输出列表。

在线尝试

说明:

def f(m):
    w=len(m)    # the height of the matrix, (at one point I thought it was the width)
    # get the anti-diagonals of the matrix. Reverse them if odd by mapping odd to -1
    d=[list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))]
            # w+len(m[0]) accounts for the width of the matrix. Works if it's too large.
    print sum(d,[]) # join the lists

Lambda的长度相同:

import numpy
lambda m:sum([list(m[::-1,:].diagonal(i)[::(i+len(m)+1)%2*-2+1])for i in range(-len(m),len(m)+len(m[0]))],[])

1

Python 3中,131个 118 115 107字节

基于与我对Deusovi挑战的回答相同的原理

我假设我们在输入矩阵中不能有零

e=enumerate
lambda s:[k for j,i in e(zip(*[([0]*n+i+[0]*len(s))for n,i in e(s)]))for k in i[::j%2*2-1]if k]

说明

这个怎么运作 :

            pad with 0      transpose    remove 0    reverse line           concatenate 
                                                     with even index
1 2 3       1 2 3 0 0        1 0 0        1            1                
4 5 6   --> 0 4 5 6 0    --> 2 4 0    --> 2 4     -->  2 4              -->  1 2 4 7 5 3 6 8 9
7 8 9       0 0 7 8 9        3 5 7        3 5 7        7 5 3             
                             0 6 8        6 8          6 8               
                             0 0 9        9            9

结果

>>> [print([i,f(i)]) for i in [[[1]], [[1, 2], [3, 1]], [[1, 2, 3, 1]], [[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]], [[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]], [[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]], [[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]], [[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]]]]
# [input,                                                          output]
[[[1]],                                                            [1]]
[[[1, 2], [3, 1]],                                                 [1, 2, 3, 1]]
[[[1, 2, 3, 1]],                                                   [1, 2, 3, 1]]
[[[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]],                     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]],                       [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]],                         [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]],                           [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]],     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]

应该reverse even linereverse odd lines呢?
nwp

@nwp指数从0开始的^^
二万

啊,您在说的是行号,而不是行的长度。我感到困惑,对不起。
nwp

@nwp np,顺便说一句,我为避免混淆而对其进行了更改
Erwan
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.