将此数组变成矩阵


13

将非嵌套数组作为输入。使用以下方法将其转换为矩阵:

假设我的数组是 [1, 2, 3, 4, 5]

首先,我将该数组重复5次:(长度)

[[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]]

然后,我沿对角线阅读:

[[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]]

我将这个数组弄平并分成五个(长度):

[[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]]

这是代码高尔夫。最少的字节数获胜。


下次,请大写内容。
奥利弗·倪

如果原始数组的长度不是5,这如何工作?

@ ais523我假设它是同一件事,您只需用长度替换“五”
Oliver Ni

我们可以假设数字始终是正整数吗?
路易斯·门多

7
@JohnCena您不应该接受第一个答案,您需要给帖子一些时间来吸引他们,并提供更多答案。
卡德

Answers:


2

05AB1E,13个字节

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

在线尝试!

说明:

                # 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

您不需要打印吗

以及您如何请求输入

1
这些打高尔夫球语言中的许多语言(例如05AB1E)都内置了用于请求输入和产生输出的默认规则,因此程序员不必在其上浪费字节。

1
输出与期望的输出实际不匹配。它不是矩阵,数字不匹配。
Karl Napf '16

1
好吧,它是一个矩阵,但是数字不正确(或者tryitonline.net计算错误)
Karl Napf

6

果冻,11字节

WẋLŒDUṙLFsL

在线尝试!

说明

               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)

嗯,当我尝试使用它时,L它做了一些奇怪的事情,因此我使用了寄存器:/我再次尝试了一下,它就可以工作了……基本上是一样的,所以我想我将删除我的寄存器。
乔纳森·艾伦

1
当然,果冻具有内置的“对角线” .... :)
格雷格·马丁

3

Python 2,105 96字节

-1和-4和-4字节归功于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)

for循环添加了描述中的项目,真正的魔力发生在这里的zip中


对垃圾邮件表示歉意,但现在R仅使用了一次,您可以直接将其放置在这里:P
FlipTack

@ Flp.Tkc没问题,我很高兴:)
Karl Napf '16

3

的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")

少打高尔夫球

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
}

测试

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>


1
哇,这是避免的非常聪明的方法return。您应该在ES6提示线程中发布有关该提示的提示。
ETHproductions 2016年

@ETHproductions范围非常狭窄。大多数情况下,评估效果更好。
edc65 '16

eval即使这次, @ ETHproductions的确确实更好:(
edc65 '16

@ETHproductions我贴了这个提示,即使它很少有用,以防万一
edc65

2

MATL,17个字节

!Gg*tRwZRhPXzGne!

在线尝试!

怎么运行的

以下说明以输入[1 2 3 4 5]为例。要显示中间结果,请%在代码中的任何语句之后插入(注释符号)。

请注意,这;是矩阵的行分隔符。所以[1 2]是行向量,[1; 2]是列向量,并且[1 0; 0 1]是2×2恒等矩阵。

!     % 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]

1

JavaScript(ES6),116个字节

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

好吧,这是一个开始...


1

R,84个字节

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

从stdin读取输入,并输出/返回R矩阵。

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

解释

关于这个答案最有趣的方面是如何获取对角线。通常,split如果提供了一个包含将对象拆分为多个因素的对象,则可以使用该函数拆分该对象。要创建这些因子,我们可以使用colrow并返回分别包含列索引和行索引的矩阵。通过求差:row(m)-col(m)我们得到一个矩阵,如:

     [,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

其中每个对角线被唯一标识。现在,我们可以基于此矩阵进行拆分,并通过应用将其变成参差不齐的列表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

(请注意,每个向量的名称如何与上面矩阵中的对角线值相对应)。

最后一步只是将其展平并将其转换为以下形式的矩阵:

     [,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

0

Mathematica 93字节

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

这是我通常编写此代码(109字节)的方式:

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

由于输入向量的顺序增加,该矩阵图从结构上给出了一个好主意。

在此处输入图片说明

这是带有随机输入向量的矩阵图。显然仍然存在一些结构。

在此处输入图片说明


0

Mathematica,92个字节

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

以列表为参数的未命名函数。这样的功能可能还有其他结构,但是希望我对这种结构打高尔夫球相当好。

第一部分n=NestList[#2,(r=Reverse)@#,(l=Length@#)-1]&定义了n两个参数的函数:第一部分是length的列表,l第二部分是应用于列表的函数。n将功能l-1时间应用于反向参数列表,并将所有结果保存在其输出列表中。(定义rl沿途只是打高尔夫球。)

n在原始列表上被调用两次,一次调用函数Rest(删除列表的第一个元素),一次调用函数Most(删除最后一个元素)。这将产生所有所需的子列表,但整个列表在那里出现两次(因此,多余的Most),而前半部分则以向后的顺序出现(因此出现r[...])。最后,~ArrayReshape~{l,l}忘记当前列表结构并将其强制为lx l数组。


0

Mathematica,85个字节

从字面上看,建议执行以下步骤:

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

我的直觉说,应该有一种聪明的方法来Part缩短时间,但是我所做的每一次尝试都超过了85个字节。


0

Ruby(110字节)

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]]

sort可能不需要执行该操作,但是Enumerable#group_by的文档不能保证哈希值(数组)中值的顺序,但是当前版本的Ruby提供了预期的顺序,如果存在sort则提供了所需的顺序从我的代码中删除。

步骤如下。

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)>

最后,f.to_a返回前面显示的数组。

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.