创建金字塔矩阵


23

金字塔矩阵是一个正方形矩阵,其中所有数字都从中心点增加或减少,例如下面的两个矩阵:

1  1  1  1  1
1  2  2  2  1
1  2  3  2  1
1  2  2  2  1
1  1  1  1  1

要么:

3  3  3  3  3
3  2  2  2  3
3  2  1  2  3
3  2  2  2  3
3  3  3  3  3

给定一个非零整数n,请创建一个金字塔矩阵,其中数字从1到中心从中心到n升序(如果n <0)或降序(如果n> 0)。如果n是偶数,则将有4个中心数字(请参见示例)。

一如既往:

  • 可选的输入和输出格式
    • 空格数,定界符等是可选的

测试用例:

1
1

-1
1

5
1  1  1  1  1  1  1  1  1
1  2  2  2  2  2  2  2  1
1  2  3  3  3  3  3  2  1
1  2  3  4  4  4  3  2  1
1  2  3  4  5  4  3  2  1
1  2  3  4  4  4  3  2  1
1  2  3  3  3  3  3  2  1
1  2  2  2  2  2  2  2  1
1  1  1  1  1  1  1  1  1

-5
5  5  5  5  5  5  5  5  5
5  4  4  4  4  4  4  4  5
5  4  3  3  3  3  3  4  5
5  4  3  2  2  2  3  4  5
5  4  3  2  1  2  3  4  5
5  4  3  2  2  2  3  4  5
5  4  3  3  3  3  3  4  5
5  4  4  4  4  4  4  4  5
5  5  5  5  5  5  5  5  5

2
1  1  1  1
1  2  2  1
1  2  2  1
1  1  1  1

-2
2  2  2  2
2  1  1  2
2  1  1  2
2  2  2  2

-4
4  4  4  4  4  4  4  4
4  3  3  3  3  3  3  4
4  3  2  2  2  2  3  4
4  3  2  1  1  2  3  4
4  3  2  1  1  2  3  4
4  3  2  2  2  2  3  4
4  3  3  3  3  3  3  4
4  4  4  4  4  4  4  4

10
为什么偶数情况与奇数情况不同?没有理由不能使矩阵都遵循完全相同的模式。
格雷格·马丁

2
因为输入应该是侧壁的长度,所以在这种情况下,奇数和偶数之间会有差异。我决定取最大值,但在那里保留了奇数和偶数差。可能看起来很奇怪,可能不是一个很好的解释,但这是为什么存在差异的解释。:-)
Stewie Griffin

2
我们可以假设-10 < n < 10吗?
泰特斯(Titus)

2
只要它看起来不是一个完美的正方形,就可以了,只要它是一个数字即可。如果10的行比10的行宽,那没关系...
Stewie Griffin

Answers:


5

果冻18 17 字节

|1ŒḄfR«þ`
AÇạẋ¡CG

在线尝试!验证所有测试用例

怎么运行的

|1ŒḄfR«þ`  Helper link. Argument: k (positive integer)

|1         Take the bitwise OR with 1. This increments k if it is even.
  ŒḄ       Bounce; yield [1, 2, ..., k | 1, ..., 2, 1].
    fR     Filter range; remove elements not in [1, ..., k] from the array.
           This results in [1, 2, ..., k, ..., 2, 1] if k is odd and in
           [1, 2, ..., k, k, ..., 2, 1] if k is even.
        `  Pass the last return value as left and right argument to:
      «þ     Minimum table; take the minimum of each pair of elements in the
             generated array, returning a 2D array.


AÇạẋ¡CG      Main link. Argument: n

A            Take the absolute value of n.
 Ç           Call the helper link on the result.
     C       Complement; yield 1 - n.
    ¡        Conditional application:
   ẋ           If repeating the return value of Ç 1 - n times results in a non-
               empty array, i.e., if n < 1:
  ạ              Take the absolute differences of the generated integers and 1 - n.
      G      Grid; join columns by spaces, rows by linefeeds.

7

EXCEL:126个字节

=MAX(MIN(MIN(CELL("row",RC)-1,CELL("col",RC)-1),MIN(((ABS(R1C1)-1)*2+3)-CELL("row",RC),((ABS(R1C1)-1)*2+3)-CELL("col",RC))),0)

在线试用 *

注意:此答案使用R1C1表示法。如果您要自己尝试。您需要在Excel选项中将其打开。

给定的公式必须存在于(2,2)以外的每个单元格中。将所需的金字塔尺寸放入(1,1)。

公式的快速屏幕截图:
在此处输入图片说明

这是条件格式的一些有趣附加图片!

*目前需要很长时间才能更新。


这不能正确处理负面案件或偶数案件。您也可以将代码缩短=MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)为92个字节。由于单元格引用未锁定,因此它仍然无法处理情况,并且无法拖动公式。
gtwebb

1
虽然有更多的高尔夫问题。=MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb

@gtwebb感谢您告诉我。我必须修复

-1。这行不通。它不处理负输入。它甚至不处理输入。如果您在每个适用的单元格中都使用此公式,则可能需要一个Range或需要一个多于126个字节的heck。
AdmBorkBork

7

蟒蛇2,109 99 98

n=input()
r=range(1,abs(n)+1)
l=r+r[~n|-2::-1]
for j in l:print[abs((n<0)*~-n+min(i,j))for i in l]

建立清单

l = [1,2,3,4,5,4,3,2,1]

并玩一点。


编辑:创建列表+ thx Lynn两个字节的新方法


If n is even, then there will be 4 center numbers

@Rod不,那不会。是什么让你这么想的?
pacholik

3
这是规则之一
Rod Rod

@罗德哦。就在几分钟前。编辑。
pacholik

2
它不是新的,只是不突出显示:c
Rod Rod

6

MATL26 24字节

oXyG|to-:"TTYaQ]G0<?G+q|

在线尝试!验证所有测试用例(略作修改的代码以用作测试套件)。

说明

该代码首先假设输入为正,构建输出数组n。将该数组初始化为1用于奇数输入,或者初始化为用于偶数输入的空数组(将其创建为大小等于输入奇偶校验的单位矩阵)。然后,n对偶数输入重复以下操作,n-1对奇数输入重复以下操作:使用包含的框架扩展数组0,并添加1到所有元素。

例如,输入步骤为n

  • 初始数组:

    1
    
  • 用框架延伸:

    0 0 0
    0 1 0
    0 0 0
    
  • 添加1

    1 1 1
    1 2 1
    1 1 1
    
  • 用框架延伸:

    0 0 0 0 0
    0 1 1 1 0
    0 1 2 1 0
    0 1 1 1 0
    0 0 0 0 0
    
  • 添加1

    1 1 1 1 1
    1 2 2 2 1
    1 2 3 2 1
    1 2 2 2 1
    1 1 1 1 1
    

这样可以为正输入提供正确的输出。如果输入为负,则需要通过减去输入1并取绝对值来修改数组:

    3 3 3 3 3
    3 2 2 2 3
    3 2 1 2 3
    3 2 2 2 3
    3 3 3 3 3

您可以在MATL Online上观看数组的增长(修改后的代码以显示中间步骤)口译员仍然是测试版。如果不起作用,请再次按“运行”或重新加载页面。

注释代码

o        % Take input implicitly and push 0 if even or 1 if odd
Xy       % Identity matrix of that size. Gives either 1 or empty array
G|       % Absolute value of input
to-      % Subtract 1 if odd
:"       % For loop: repeat that many times
  TTYa   %   Add a frame of zeros in the two dimensions
  Q      %   Add 1 to all elements
]        % End for
G        % Push input again
0>       % is it negative?
?        % If so
  G      %   Push input again
  +      %   Add
  q      %   Subtract 1
  |      %   Absolute value
         % End if implicitly
         % Display implicitly

我看到您重用了动画问题中的代码。太棒了!有趣的是,即使该代码比您的其他版本更长,该代码仍会在该问题中胜出;)。
魔术章鱼缸

1
@carusocomputing是的,类似:复制,显示,暂停1秒,清除输出:-)
Luis Mendo

另外,不确定为什么,但是14之上的任何输入都将在14处停止。请取消,这是在线控制台“操作超时”的限制。
魔术章鱼缸

@carusocomputing错误显示“操作超时”。我想对于口译员来说只需要太长时间。尝试减少停留时间,以.2秒为单位
Luis Mendo

@carusocomputing是的,这是在线解释器上的超时。我们目前将工作限制为30秒。正如路易斯建议的那样,您可以减少暂停时间
Suever 2016年

3

Python 2.7: 123 122 120字节

概率仍然可以节省一些字节...

from numpy import*
n=input()
N=abs(n)
e=N*2-N%2
a=ones([e,e])
for i in range(N):a[i:e-i,i:e-i]=(i+1)*(n>0)or-n-i
print a

edit1:N=abs(n)保存1个字节

edit2:(i+1)*(n>0)or-n-i保存2个字节


3

Haskell中,119个 113 110 104 102 101字节

f x|(h,t)<-splitAt(mod x 2)$[x,x-1..1]++[1.. -x]=foldl(\m n->(n#)<$>(n<$m)#m)[[y]|y<-h]t
x#y=x:y++[x]

以整数列表的形式返回矩阵,例如:f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]]

怎么运行的:

            [x,x-1..1]++[1.. -x]      -- make list from x down to 1 followed by
                                      -- 1 to (-x). One of the sublists will be
                                      -- empty. The resulting list contains the
                                      -- numbers of the pyramid from inside to out.
   (h,t)<-splitAt(mod x 2)            -- bind h to the first element if x is odd
                                      -- or to the empty list if x is even
                                      -- bind t to the rest (tail or full list)

foldl (     ) [[y]|y<-h] t            -- fold the following function into t with a
                                      -- starting value of [] if x is even or
                                      -- [[h]] if x is odd

   \m n ->                            -- the current matrix m with the next number
                                      -- n is transformed into a new matrix:

               (n#)<$>(n<$m)#m        -- prepend and append a n to 
                                      -- m prepended and append by a line of n's

x#y=x:y++[x]                          -- helper function to prepend and append an
                                      -- element x to a list y

2

Perl,175个字节

包含1个字节的-p

($t,$v,$w)=($_,(abs)x2);$k=$_.$k for 1..$v;map{$r.=$_ for(@v=1..$_-1),$_ x(2*$v---$w%2),reverse@v;$r.=$/}1..$v;$_=$r.~~reverse$r;eval"y/1-$w/$k/"if$t<0;$w%2&&s/

.*//||s;

;

(有一个尾随的换行符,我不知道如何用降价显示,但是您需要它)。

需求-p以及-M5.010-E运行:

perl -pE '($t,$v,$w)=($_,(abs)x2);$k=$_.$k for 1..$v;map{$r.=$_ for(@v=1..$_-1),$_ x(2*$v---$w%2),reverse@v;$r.=$/}1..$v;$_=$r.~~reverse$r;eval"y/1-$w/$k/"if$t<0;$w%2&&s/

.*//||s;

;
' <<< 5

该死,这太长了……我会在有空的时候尝试其他方法。


为什么使用eval
泰特斯(Titus)

@Titus因为y///不进行插值,所以使用双引号对$wand 进行插值$k,然后eval执行y///
达达

2

Python 2,109字节

n=input()
a=abs(n)
s=a*2-a%2
r=range(s)
for y in r:print[(min,max)[n<0](x+1,s-x,y+1,s-y)-(n<0)*s/2for x in r]

2

J,29 26字节

1+**[:<./~**i.,2&|1&}.i.@-

用法

   f =: 1+**[:<./~**i.,2&|1&}.i.@-
   f 1
1
   f _1
1
   f 2
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
   f _2
2 2 2 2
2 1 1 2
2 1 1 2
2 2 2 2
   f 3
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
   f _3
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3

说明

范围i.动词输出[0, 1, ..., n-1]为正n[n-1, n-2, ..., 0]为负n,其在这里是有用的。

1+**[:<./~**i.,2&|1&}.i.@-  Input: integer n
                         -  Negate n
                      i.@   Creates range for -n
               2&|          Take n modulo 2, returns 0 or 1
                  1&}.      If n is odd, drop the first value from the range for -n
                            Else do nothing and pass it unmodified
              ,             Append it to
            i.              The range for n
          *                 Get the sign of n
           *                Multiply elementwise with the joined ranges
    [:<./~                  Form a table of the minimum values of the range
  *                         Get the sign of n
   *                        Multiply elementwise with the joined ranges
1+                          Add 1 to each and return

2

Mathematica,78个字节

Abs[Fold[ArrayPad[#,1,#2]&,Table[0,#,#]&@Mod[#,2,1],Range[Abs@#-1]]+1~Min~-#]&

说明

Table[0,#,#]&@Mod[#,2,1]

制作初始矩阵:如果是奇数,则为1x1;如果是偶数,则为2x2。

Range[Abs@#-1]

生成一个从1到abs(input)-1的列表。

Fold[ArrayPad[#,1,#2]&, ..., ...]

使用上述列表填充初始数组。

... +1~Min~-#

加1或-input,以较小者为准。

Abs

将绝对值应用于整个矩阵。


1

PHP,177157字节

for($y=-$n=abs($z=$argv[1])+1;++$y<$n;)if($y&&($n&1||$y-1)){for($x=-$n;++$x<$n;)if($x&&($n&1||$x-1)){$v=max(abs($x),abs($y));echo$z<0?$v:$n-$v," ";}echo"
";}

php -r '<code>

遍历行和列,并根据它们到中心的距离打印值。

  • $n=abs($z)+1+1保存两个+1-1以后的表达式
  • 循环从-$n+1(在条件中预先增加!)到$n-1-abs($z)abs($z)
  • 行/列0(奇数$n:1)被跳过
    $n&1这里偶数列是正确的!记住+1吗?)
  • 正数$ z的打印也受益于+1

1

Haskell中,191个 183 173 169 168字节

r=reverse;m=map
x!y=(((++)<*>(x.r)).).zipWith(++).m y
g n|n<0=m(m$abs.((n-1)+)).g$abs n|1<2=[id!id,tail!init]!!mod n 2=<<m r$r$m(\x->(x<$[1..x])++[x+1..n])[1..n]
g.(0-)

用法:

mapM_ print $ (g.(0-)) 3

[1,1,1,1,1]
[1,2,2,2,1]
[1,2,3,2,1]
[1,2,2,2,1]
[1,1,1,1,1]

感谢nimi提供2 10 20 24字节!


1
negate(0-)
nimi

1
您可以更改f[id!id,tail!init]!!mod n 2,然后将其内联到其中,g并使用1<2防护来绑定分支的中间结果:g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n。您不需要主要功能的名称。
nimi

1
哦,你可以内联a,太(和切换回1<2后卫): g n| ... |1<2=[id!id,tail!init]!!mod n 2=<<map r$r$(\x->(x<$[1..x])++[x+1..n])<$>[1..n]
nimi

1
今天的最后一个::m=map,位于!...(++).m yg:中g n|n<0=m(m(abs.((n-1)+)))$g$abs n|1<2=[id!id,tail!init]!!mod n 2=<<m r$r$m(\x->(x<$[1..x])++[x+1..n])[1..n]
nimi

1

JavaScript(ES6),107个字节

(n,l=Math.abs(n+n-n%2))=>[...Array(l--)].map((_,i,a)=>a.map((_,j)=>(j=Math.min(i,l-i,j,l-j),n<0?-n-j:j+1)))

l是数组的大小。在n<0?-n-j:j+1看起来别扭,但我不能找到更好的东西。


1

Vim, 152个 143字节

我敢肯定,这可能会打得更多,尤其是最后两行,但是我的大脑被炸了。

D:let@z=@-/abs(@-)
a"nywYp:s/\d/x/g<C-v>
YggP:%s/.*/x \0 x<C-v>
:%s/x\+/\=@n-@z/g<C-v>
<Esc>v0"qda<C-r>=@z<0?1:@-*@z
<Esc>@=@-%2?"":"YPJYp"
@=@-*@z-1.(@-*@z>1?"@q":"")

在线尝试!

这是xxd格式,带有不可打印的字符:

0000000: 443a 6c65 7440 7a3d 402d 2f61 6273 2840  D:let@z=@-/abs(@
0000010: 2d29 0a61 226e 7977 5970 3a73 2f5c 642f  -).a"nywYp:s/\d/
0000020: 782f 6716 0a59 6767 503a 2573 2f2e 2a2f  x/g..YggP:%s/.*/
0000030: 7820 5c30 2078 160a 3a25 732f 785c 2b2f  x \0 x..:%s/x\+/
0000040: 5c3d 406e 2d40 7a2f 6716 0a1b 7630 2271  \=@n-@z/g...v0"q
0000050: 6461 123d 407a 3c30 3f31 3a40 2d2a 407a  da.=@z<0?1:@-*@z
0000060: 0a1b 403d 402d 2532 3f22 223a 2259 504a  ..@=@-%2?"":"YPJ
0000070: 5970 220a 403d 402d 2a40 7a2d 312e 2840  Yp".@=@-*@z-1.(@
0000080: 2d2a 407a 3e31 3f22 4071 223a 2222 29    -*@z>1?"@q":"")

说明

它从中心向外构建金字塔,并用xes 包围中心编号:

x x x
x 5 x
x x x

然后x用下一个数字替换es并x再次用es 包围它:

x x x x x
x 4 4 4 x
x 4 5 4 x
x 4 4 4 x
x x x x x

...等等。对于偶数,它执行相同的操作,但以2x2为基数开始。

这是代码“解开”。这有点不合常规,因为我通过将其键入缓冲区(因此将所有<C-v>s)然后将其删除到寄存器中来“记录”宏,这是我发现无需实际执行按键操作即可组成宏的最佳方法。

D:let@z=@-/abs(@-)<CR>       " Delete the input (into @-) and set @z to -1 if @- is negative; otherwise 1
a                            " Enter insert mode to compose the macro
  "nyw                         " Copy the number under the cursor to @n
  Yp                           " Copy this line and paste it below
  :s/\d/x/g<C-v><CR>           " Replace digits in the copy with 'x'
  YggP                         " Copy this line and paste it at the top of the buffer
  :%s/.*/x \0 x<C-v><CR>       " Add an 'x' before and after each line
  :%s/x\+/\=@n-@z/g<C-v><CR>   " Replace all 'x'es (and 'xx'es etc.) with the next number
<Esc>v0"qd                   " Done composing macro; delete it into @q (buffer is now empty)
a<C-r>=@z<0?1:@-*@z          " Append the center number (1 or abs(@-)) to the buffer
<Esc>@=@-%2?"":"YPJYp"       " If the input is even, make a 2x2 square
@=@-*@z-1.(@-*@z>1?"@q":"")  " Execute the macro abs(@-)-1 times if it's > 1

0

PHP,215字节

for($i=0;$i<$m=($r=($s=abs($n=$argv[1]))*2-$s%2)**2;){$i%$r?:print"\n";$l=min(($x=$i%$r+1)<$s?$x:$x=$r-$x+1,($z=1+floor($i++/$r))<$s?$z:$z=$r-$z+1);$o=($n>0)?$l:$s+1-$l;echo str_pad(" ",1+strlen($s)-strlen($o)).$o;}

0

R,112字节

k=abs(n);l=2*k;m=diag(l);for(i in 1:k){m[i:(l+1-i),i:(l+1-i)]=i};if(n%%2==1){m=m[-k,-k]};if(n<0){m=abs(m-1+n)};m

n在工作空间中需要整数,否则需要n=scan()额外运行8个字节。

k=abs(n)
l=2*k
m=diag(l)                    # Initialize quadratic 2*|n| matrix
for(i in 1:k){
    m[i:(l+1-i),i:(l+1-i)]=i # Assign values to matrix elements according
                             # to their index
}
if(n%%2==1){
   m=m[-k,-k]                # If n is odd, delete middle row and column
}
if(n<0){
    m=abs(m-1+n)             # If n < 0, flip values
}
m                            # Print matrix
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.