折叠矩阵!


13

给定一个矩阵,向上/向下或向左/向右累加其值以形成一个X,向上折叠,然后返回列表。我在这里描述算法:

算法

您的输入将是您语言的合理数值范围内的整数的奇数方阵。

让我们以下面的矩阵为例:

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

首先,将每个数字加到主对角线或反对角线上最接近的数字。也就是说,将矩阵沿主对角线和反对角线分为四个部分,然后将每个部分中朝向中心的所有数字相加,如下所示:

1   2   3   2   1
    ↓   ↓   ↓    
0 → 3   2   3 ← 0
        ↓        
4 → 2 → 5 ← 6 ← 3
        ↑        
7 → 4   7   9 ← 4
    ↑   ↑   ↑    
0   6   7   2   5

此步骤将产生以下结果:

1        1
  5    5
    39
  17  15
0        5

然后,我们通过展平X并将元素与左上角先到左下角交织来折叠它。得到以下结果:

1, 0, 5, 17, 39, 5, 15, 1, 5

您可以想象这是拉伸主对角线并逆时针旋转它。

这是最终结果。

挑战

实现此算法。有标准漏洞。可接受所有合理的I / O格式。

测试用例

Input
Output

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

1, 0, 5, 17, 39, 5, 15, 1, 5

1 2 3 4 5
5 4 3 2 1
1 3 5 7 9
0 9 8 7 6
6 7 8 9 0

1, 6, 11, 16, 47, 7, 22, 5, 0

1 3 7 4 8 5 3
8 4 7 5 3 8 0
0 6 3 6 9 8 4
2 6 5 8 7 4 2
0 6 4 3 2 7 5
0 6 7 8 5 7 4
8 5 3 2 6 7 9

1, 8, 15, 11, 23, 20, 62, 32, 25, 13, 18, 3, 9

您可以添加“非5×5”矩阵测试用例吗?
完全人类

1
@icrieverytim,在这里
-HyperNeutrino

Answers:


7

JavaScript,113字节

s=>(l=s.length-1,a=[],s.map((v,y)=>v.map((n,x)=>a[q=2*[x,y,l-y].sort((u,v)=>u-v)[1]+(y>l/2),q-=q>l]=~~a[q]+n)),a)


嗯..为什么~~?它们彼此抵消,因此不需要它们。
凯文·克鲁伊森

2
@KevinCruijssen ~~undefined==0,所以比(a[q]||0)
尼尔

@Neil啊,没想到undefined。当我复制使用的tsh测试用例时,我注意到它在没有的情况下可以工作~~。而且由于彼此之间~~x是相似的-(-x),所以我认为它是偶然地放在那儿的。感谢您的更正。
凯文·克鲁伊森

5

果冻25 23 21字节

AṂ×ṠṚ
LHŒRṗ2Ç€ḅLĠịFS€

在线尝试!

替代版本,19字节

AṂ×ṠṚ
LHŒRṗ2Ç€ĠịFS€

Ġ没用,因为嵌套数组的行为不正确。唯一的不同是,“ 如何工作”中提到的对[q,p]是按字典顺序排序的,而不是在排序之前将它们映射为p + nq

在线尝试!

背景

我们先用坐标替换其元素,然后向左和向下增加,然后将(0,0)放在矩阵的中心。

对于7x7的矩阵M,我们得到以下坐标。

(-3,-3) (-3,-2) (-3,-1) (-3, 0) (-3, 1) (-3, 2) (-3, 3)
(-2,-3) (-2,-2) (-2,-1) (-2, 0) (-2, 1) (-2, 2) (-2, 3)
(-1,-3) (-1,-2) (-1,-1) (-1, 0) (-1, 1) (-1, 2) (-1, 3)
( 0,-3) ( 0,-2) ( 0,-1) ( 0, 0) ( 0, 1) ( 0, 2) ( 0, 3)
( 1,-3) ( 1,-2) ( 1,-1) ( 1, 0) ( 1, 1) ( 1, 2) ( 1, 3)
( 2,-3) ( 2,-2) ( 2,-1) ( 2, 0) ( 2, 1) ( 2, 2) ( 2, 3)
( 3,-3) ( 3,-2) ( 3,-1) ( 3, 0) ( 3, 1) ( 3, 2) ( 3, 3)

现在,我们计算每个坐标对的最小绝对值,并将两个坐标对的符号乘以它,将(i,j)映射到(sign(i)m,sign(j)m),其中m = min(| i | ,| j |)

(-3,-3) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-3, 3)
(-2,-2) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-2, 2)
(-1,-1) (-1,-1) (-1,-1) ( 0, 0) (-1, 1) (-1, 1) (-1, 1)
( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0)
( 1,-1) ( 1,-1) ( 1,-1) ( 0, 0) ( 1, 1) ( 1, 1) ( 1, 1)
( 2,-2) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 2, 2)
( 3,-3) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 3, 3)

对应于同一对的矩阵元素必须相加。为了确定总和的顺序,我们将每对(p,q)映射到p + nq,其中nM的行数/列数。

-24 -16  -8   0   6  12  18
-16 -16  -8   0   6  12  12
 -8  -8  -8   0   6   6   6
  0   0   0   0   0   0   0
 -6  -6  -6   0   8   8   8
-12 -12  -6   0   8  16  16
-18 -12  -6   0   8  16  24

总和的顺序对应于整数的顺序,而整数的顺序对应于其求和。

怎么运行的

LHŒRṗ2Ç€ḅLĠịFS€  Main link. Argument: M (matrix)

L                Compute n, the length (number of rows) of M.
 H               Halve it.
  ŒR             Symmetric range; map t to [-int(t), ..., 0, int(t)].
    ṗ2           Compute the second Cartesian power, yielding all pairs [i, j]
                 with -t ≤ i, j ≤ t.
      ǀ         Map the helper link over the resulting array of pairs.
         L       Yield n.
        ḅ        Unbase; map each pair [q, p] to (p + nq).
          Ġ      Group the indices of the resulting array of n² integers by their
                 corresponding values, ordering the groups by the values.
            F    Flatten M.
           ị     Index into the serialized matrix.
             S€  Compute the sum of each group.


AṂ×ṠṚ            Helper link. Argument: [i, j] (index pair)

A                Absolute value; yield [|i|, |j|].
 Ṃ               Minimum; yield m := min(|i|, |j|).
   Ṡ             Sign; yield [sign(i), sign(j)].
  ×              Multiply; yield [p, q] := [sign(i)m, sign(j)m].
    Ṛ            Reverse; yield [q, p].

5
这真是太好了。
Uriel

5

Python,159158字节

def f(m):l=len(m)-1;r=range(1,l);return m[0][::l]+f([[sum(m[x][1%y*y:(y>l-2)-~y])+m[0][y]*(x<2)+m[l][y]*(x>l-2)for y in r]for x in r])+m[l][::l]if l else m[0]

在线尝试!


1
y+1+(y>l-2)可以(y>l-2)-~y
乔纳森·弗雷希


2

APL(Dyalog),60字节*

与我的同事马歇尔(Marshall)合作。

匿名前缀lambda。以矩阵为参数并返回向量。假设⎕IO (I ndex O rigin)为零,这在许多系统上都是默认值。

{(,⍉{+/,(s×-×⍺)↓⍵×i∊¨⍨s←⌊⊃r÷2}⌺r⊢⍵)/⍨,(⊢∨⌽)=/¨i←⍳r←⍴⍵}

在线尝试!

{} 匿名lambda;是正确的参数(作为希腊字母的最右边的字母):

⍴⍵ 参数的形状(两个相同元素的列表)

r← 存储为r(如在r ho中)

 所有ɩ该大小的数组的ndices,即(0 0)(0 1)...

i← 存储在i(如在 OTA)

=/¨ 坐标相等的布尔值(即对角线)

() 应用此匿名默认前缀功能:

   推论

  ⊢∨ 或者使用未经修改的参数

, ravel(整理成简单列表)

 现在,我们有一个对角线的布尔蒙版。

()/⍨ 使用它来过滤以下内容:

  ⊢⍵ 得到(从分离r)参数

  {}⌺r 在每个元素上调用以下匿名中缀lambda,将r-neighbourhood(根据需要用零填充)作为正确的参数(),并用两元素列表填充行数,列(底数/右数为负,零表示无)作为左参数():

   r÷2 一分为r

    选择第一个元素(它们是相同的)

    铺地板

   s← 存储为s(用于s hape)

   i∊⍨¨ 对于的每个元素i,如果s为Boolean,则为Boolean

   ⍵× 与之相乘

   ()↓ 删除以下行和列数(负数表示底部/右侧):

    ×⍺ 左参数的符号(即填充的方向)

    - 否定

    s与之 相乘

   , 拉夫(拉直到列表中)

   +/ 总和(加减)

现在我们有了完整的和矩阵,但是我们需要过滤按列读取的所有值。

   转置

  , ravel(整理成简单列表)


*计算⎕U233A 在线尝试!

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.