Tạo ma trận hình chóp


23

Ma trận hình chóp là một ma trận vuông trong đó tất cả các số tăng hoặc giảm từ điểm trung tâm, giống như hai ma trận dưới đây:

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

Hoặc là:

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

Với một tổ chức phi zero số nguyên n, tạo ra một ma trận hình chóp nơi những con số đi từ 1để nmột trong hai thứ tự tăng dần (nếu n <0), hoặc giảm theo thứ tự (nếu n> 0) từ trung tâm. Nếu nlà số chẵn thì sẽ có 4 số chính giữa (xem ví dụ).

Như mọi khi:

  • Tùy chọn định dạng đầu vào và đầu ra
    • Số lượng không gian, dấu phân cách, vv là tùy chọn

Các trường hợp thử nghiệm:

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
Tại sao trường hợp chẵn khác với trường hợp lẻ? Không có lý do tại sao tất cả các ma trận không thể theo cùng một mẫu chính xác.
Greg Martin

2
Bởi vì đầu vào được cho là chiều dài của bức tường bên, trong trường hợp đó có sự khác biệt giữa lẻ và chẵn. Tôi quyết định đi theo giá trị tối đa thay thế, nhưng vẫn giữ sự khác biệt và thậm chí khác biệt ở đó. Nó có vẻ lạ, và có thể không phải là một lời giải thích tốt, nhưng đó là lời giải thích cho lý do tại sao có sự khác biệt. :-)
Stewie Griffin

2
Chúng ta có thể giả định -10 < n < 10?
Tít

2
Đó là ok nếu nó không trông giống như một hình vuông hoàn hảo, miễn là nó đó là một phát biểu về số lượng. Nếu các hàng có nhiều số 10 rộng hơn so với các hàng có số 10 thì không sao ...
Stewie Griffin

Câu trả lời:


5

Thạch , 18 17 byte

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

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

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

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

Dùng thử trực tuyến *

Lưu ý: câu trả lời này sử dụng Ký hiệu R1C1. Nếu bạn sẽ tự mình thử điều này. bạn cần bật nó trong tùy chọn Excel.

công thức đã cho cần phải có trong mọi ô hiện diện ngoài (2,2). Đặt kích thước kim tự tháp mong muốn của bạn vào (1,1).

nắp màn hình nhanh của công thức đang hoạt động:
nhập mô tả hình ảnh ở đây

Dưới đây là một hình ảnh bổ sung của một số niềm vui với định dạng có điều kiện!

* Hiện tại phải mất một thời gian rất dài để cập nhật.


Điều này không xử lý các trường hợp tiêu cực hoặc các trường hợp thậm chí đúng. Ngoài ra, bạn có thể rút ngắn mã =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)là 92 byte. Nó vẫn không xử lý các trường hợp mặc dù và công thức không thể được kéo qua vì tham chiếu ô không bị khóa.
gtwebb

1
Nhiều vấn đề golf tương tự mặc dù. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb

@gtwebb cảm ơn đã cho tôi biết. Tôi sẽ phải sửa

-1. Điều này không hoạt động. Nó không xử lý đầu vào tiêu cực. Nó không xử lý ngay cả đầu vào. Nếu bạn đang đưa công thức này vào mọi ô có thể áp dụng, bạn cần một Rangehoặc bạn cần một số lượng lớn hơn 126 byte.
admBorkBork

7

Con trăn 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]

Tạo danh sách

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

và chơi với nó một chút.


chỉnh sửa: cách tạo danh sách mới + thx Lynn cho hai byte


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

@Rod Không có. Điều gì làm bạn nghĩ như vậy?
pacholik

3
đây là một trong những quy tắc
Rod

@Rod ơi. Chỉ vài phút trước. Đã chỉnh sửa.
pacholik

2
Nó không phải là mới, chỉ là không được tô sáng: c
Rod

6

MATL , 26 24 byte

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

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm (mã được sửa đổi một chút để phục vụ như bộ thử nghiệm).

Giải trình

Mã đầu tiên xây dựng mảng đầu ra giả sử đầu vào tích cực n. Mảng được khởi tạo như 1đối với đầu vào lẻ ​​hoặc là mảng trống cho đầu vào chẵn (điều này được tạo dưới dạng ma trận danh tính với kích thước bằng với mức tương đương của đầu vào). Sau đó, lần sau là nthời gian lặp lại cho đầu vào chẵn và n-1thời gian cho đầu vào lẻ: mở rộng mảng với khung chứa 0và thêm 1vào tất cả các phần tử.

Ví dụ: các bước cho đầu vào nlà:

  • Mảng ban đầu:

    1
    
  • Mở rộng với khung:

    0 0 0
    0 1 0
    0 0 0
    
  • Thêm 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Mở rộng với khung:

    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
    
  • Thêm 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
    

Điều này cho đầu ra chính xác cho đầu vào tích cực. Nếu đầu vào là âm, mảng cần được sửa đổi bằng cách thêm âm đầu vào 1và lấy giá trị tuyệt đối:

    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

Bạn có thể xem mảng đang phát triển (mã được sửa đổi để hiển thị các bước trung gian) tại MATL Online!Trình thông dịch vẫn là bản beta. Nếu nó không hoạt động, nhấn "Chạy" lại hoặc tải lại trang.

Mã nhận xét

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

Tôi thấy bạn đã sử dụng lại mã từ câu hỏi hoạt hình. Tuyệt vời! Điều thú vị là, mã này vẫn sẽ giành chiến thắng trong câu hỏi đó, mặc dù nó dài hơn phiên bản khác của bạn;).
Bạch tuộc ma thuật Urn

1
@carusocomputing Có, nó tương tự: trùng lặp, hiển thị, tạm dừng 1 giây, đầu ra rõ ràng :-)
Luis Mendo

Ngoài ra, không chắc chắn tại sao, nhưng bất kỳ đầu vào nào trên 14 dừng lại ở 14. Hủy bỏ điều đó, đó là một hạn chế của bảng điều khiển trực tuyến "Đã hết thời gian hoạt động".
Bạch tuộc ma thuật Urn

@carusocomputing Lỗi báo "hết thời gian hoạt động". Tôi đoán nó chỉ mất quá nhiều thời gian cho phiên dịch viên. Hãy thử giảm tạm dừng để nói .2giây
Luis Mendo

@carusocomputing Có, đó là thời gian chờ của trình thông dịch trực tuyến. Chúng tôi hiện giới hạn công việc trong 30 giây. Như Luis đề xuất, bạn có thể giảm thời gian tạm dừng
Suever

3

Python 2.7: 123 122 120 byte

probs vẫn có thể lưu một vài byte ...

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

chỉnh sửa1: N=abs(n)để lưu 1 byte

chỉnh sửa2: (i+1)*(n>0)or-n-iđể lưu 2 byte


3

Haskell, 119 113 110 104 102 101 byte

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]

Trả về ma trận dưới dạng danh sách các số nguyên, ví dụ: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Làm thế nào nó hoạt động:

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

Bao gồm 1 byte cho -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;

;

(Có một dòng mới mà tôi không biết cách hiển thị với phần đánh dấu, nhưng bạn cần nó).

Nhu cầu -pcũng như -M5.010hoặc -Eđể chạy:

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

Chết tiệt, cái này quá dài ... Tôi sẽ thử một số cách tiếp cận khác khi tôi có thời gian.


Tại sao bạn sử dụng eval?
Tít

@Titus Vì y///không nội suy, nên sử dụng dấu ngoặc kép để nội suy $w$ksau đó evalđể thực thi y///.
Dada

2

Python 2, 109 byte

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 byte

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

Sử dụng

   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

Giải trình

Các i.đầu ra động từ phạm vi [0, 1, ..., n-1]cho tích cực n[n-1, n-2, ..., 0]tiêu cực nlà hữu ích ở đây.

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

Toán học, 78 byte

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

Giải trình

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

Tạo ma trận ban đầu: 1x1 nếu lẻ, 2x2 nếu chẵn.

Range[Abs@#-1]

Tạo danh sách từ 1 đến abs (đầu vào) - 1.

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

Pad mảng ban đầu bằng cách sử dụng danh sách nói trên.

... +1~Min~-#

Thêm 1 hoặc -input, cái nào nhỏ hơn.

Abs

Áp dụng giá trị tuyệt đối cho toàn bộ ma trận.


1

PHP, 177 157 byte

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"
";}

chạy với php -r '<code>

vòng lặp qua các hàng và cột, in các giá trị tùy thuộc vào khoảng cách của chúng đến trung tâm.

  • $n=abs($z)+1: Các +1 lưu một vài +1-1trong các biểu thức sau
  • các vòng lặp đi từ -$n+1(tăng trước trong điều kiện!) đến$n-1 ( -abs($z)đến abs($z))
  • dòng / cột 0 (và cho số lẻ $n: 1) được bỏ qua
    ( $n&1có đúng với các cột chẵn ở đây không! Hãy nhớ +1?)
  • Việc in cho $ z dương cũng có lợi từ +1.

1

Haskell, 191 183 173 169 168 byte

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

Sử dụng:

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]

Cảm ơn nimi cho 2 10 20 24 byte!


1
negate(0-)
nimi

1
Bạn có thể thay đổi fđể [id!id,tail!init]!!mod n 2rồi inline nó vào gvà sử dụng 1<2bảo vệ để ràng buộc một kết quả trung gian của các chi nhánh: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Bạn không cần một tên cho chức năng chính.
nimi

1
Ồ, bạn cũng có thể nội tuyến a(và chuyển trở lại 1<2bảo vệ) : 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
Cuối cùng cho ngày hôm nay : m=map, trong !: ...(++).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 byte

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

llà kích thước của mảng. Có n<0?-n-j:j+1vẻ khó xử nhưng tôi không thể tìm thấy bất cứ điều gì tốt hơn.


1

Vim, 152 143 byte

Tôi chắc chắn rằng điều này có thể được chơi golf nhiều hơn, đặc biệt là hai dòng cuối cùng, nhưng bộ não của tôi là chiên.

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

Hãy thử trực tuyến!

Đây là định dạng xxd với các ký tự không thể in được:

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

Giải trình

Nó xây dựng kim tự tháp từ trung tâm ra ngoài, bao quanh số trung tâm với xes:

x x x
x 5 x
x x x

Sau đó, nó thay thế xes bằng số tiếp theo và bao quanh nó với xes một lần nữa:

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

... và cứ thế. Đối với các số chẵn, nó làm điều tương tự nhưng bắt đầu với cơ sở 2x2.

Đây là mã "vô danh." Điều đó hơi khác thường ở chỗ tôi "ghi lại" một macro bằng cách nhập nó vào một bộ đệm (do đó tất cả các <C-v>s) và sau đó xóa nó vào một thanh ghi, đó là cách tốt nhất tôi tìm thấy để soạn một macro mà không thực sự gõ phím.

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 byte

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 byte

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

Cần số nguyên ntrong không gian làm việc, nếu không thì chạy n=scan()thêm 8 byte.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.