Buat matriks piramidal

23

Matriks piramidal adalah matriks persegi di mana semua angka bertambah atau berkurang dari titik pusat, seperti dua matriks di bawah ini:

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

Atau:

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

Diberikan integer non-nol n, buat matriks piramidal di mana angka berubah dari baik 1ke ndalam urutan yang meningkat (jika n <0), atau urutan menurun (jika n> 0) dari pusat. Jika ngenap, maka akan ada 4 angka pusat (lihat contoh).

Seperti biasa:

  • Input dan format output opsional
    • Jumlah spasi, pembatas, dll. Bersifat opsional

Kasus uji:

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
Stewie Griffin
sumber
10
Mengapa kasing berbeda dari kasing aneh? Tidak ada alasan mengapa semua matriks tidak dapat mengikuti pola yang sama persis.
Greg Martin
2
Karena input seharusnya panjang dinding samping, dalam hal ini ada perbedaan antara ganjil dan genap. Saya memutuskan untuk pergi untuk nilai maksimum sebagai gantinya, tetapi menyimpan perbedaan yang aneh dan genap di sana. Ini mungkin tampak aneh, dan mungkin bukan penjelasan yang baik, tapi itu penjelasan mengapa ada perbedaan. :-)
Stewie Griffin
2
Bisakah kita berasumsi -10 < n < 10?
Titus
2
Tidak apa-apa jika tidak terlihat seperti bujur sangkar yang sempurna, asalkan itu berbentuk angka. Jika baris dengan banyak 10 lebih luas daripada yang dengan sedikit 10 maka tidak apa-apa ...
Stewie Griffin

Jawaban:

5

Jelly , 18 17 byte

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

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

|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.
Dennis
sumber
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)

Cobalah online *

Catatan: jawaban ini menggunakan Notasi R1C1. Jika Anda akan mencoba ini sendiri. Anda perlu mengaktifkannya di opsi Excel.

rumus yang diberikan harus ada di setiap sel yang ada di luar (2,2). Masukkan ukuran piramida yang Anda inginkan ke dalam (1,1).

tutup layar cepat dari rumus yang sedang beraksi:
masukkan deskripsi gambar di sini

Berikut ini adalah gambar tambahan yang menyenangkan dengan pemformatan bersyarat!

* Butuh waktu sangat lama untuk memperbarui, saat ini.


sumber
Ini tidak menangani kasus negatif atau bahkan kasus dengan benar. Anda juga dapat mempersingkat kode =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)yang 92 byte. Itu masih tidak menangani kasus dan rumus tidak dapat diseret karena referensi sel tidak dikunci.
gtwebb
1
Lebih banyak bermain golf masalah yang sama. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb
@ gtwebb terima kasih telah memberi tahu saya. Saya harus memperbaikinya
-1. Ini tidak bekerja Itu tidak menangani input negatif. Itu tidak menangani input bahkan. Jika Anda memasukkan formula ini di setiap sel yang berlaku, Anda memerlukan Rangeatau membutuhkan lebih dari 126 byte.
AdmBorkBork
7

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

Buat daftar

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

dan bermain dengannya sedikit.


sunting: cara baru membuat daftar + thx Lynn untuk dua byte

pacholik
sumber
If n is even, then there will be 4 center numbers
Rod
@Rod Tidak tidak akan ada. Apa yang membuat Anda berpikir begitu?
pacholik
3
ini adalah salah satu aturan
Rod
@ Oh Oh. Beberapa menit yang lalu. Diedit.
pacholik
2
Itu bukan hal baru, hanya saja tidak disorot: c
Rod
6

MATL , 26 24 byte

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

Cobalah online! Atau verifikasi semua test case (kode yang sedikit dimodifikasi untuk dijadikan sebagai test suite).

Penjelasan

Kode pertama membangun array output dengan asumsi input positif n. Array diinisialisasi 1untuk input ganjil atau sebagai array kosong untuk input genap (ini dibuat sebagai matriks identitas dengan ukuran sama dengan paritas input). Kemudian berikut ini adalah nwaktu yang diulang untuk input genap, dan n-1waktu untuk input ganjil: perpanjang array dengan bingkai yang berisi 0, dan tambahkan 1ke semua elemen.

Sebagai contoh, langkah-langkah untuk input nadalah:

  • Array awal:

    1
    
  • Perpanjang dengan bingkai:

    0 0 0
    0 1 0
    0 0 0
    
  • Tambahkan 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Perpanjang dengan bingkai:

    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
    
  • Tambahkan 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
    

Ini memberikan output yang benar untuk input positif. Jika input negatif, array perlu dimodifikasi dengan menambahkan minus input 1dan mengambil nilai absolut:

    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

Anda dapat menyaksikan peningkatan array (kode yang dimodifikasi untuk menampilkan langkah-langkah lanjutan) di MATL Online! Penerjemahnya masih versi beta. Jika tidak berhasil tekan "Jalankan" lagi atau muat ulang halaman.

Kode yang dikomentari

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
Luis Mendo
sumber
Saya melihat Anda menggunakan kembali kode dari pertanyaan animasi. Luar biasa! Bagian yang lucu adalah, kode ini juga akan tetap menang dalam pertanyaan itu, meskipun lebih lama dari versi Anda yang lain;).
Magic Octopus Urn
1
@carusocomputing Ya, ini mirip: duplikat, tampilan, jeda 1 detik, keluaran jelas :-)
Luis Mendo
Juga, tidak yakin mengapa, tetapi setiap input di atas 14 berhenti pada 14. Batalkan itu, ini adalah batasan dari konsol online "Waktu habis operasi".
Magic Gurita Guci
@carusocomputing Kesalahan mengatakan "waktu operasi habis". Saya kira itu terlalu lama untuk penerjemah. Coba kurangi waktu jeda itu menjadi .2detik
Luis Mendo
@carusocomputing Ya itu batas waktu pada penerjemah online. Kami saat ini membatasi pekerjaan hingga 30 detik. Seperti yang disarankan Luis, Anda dapat mengurangi waktu jeda
Suever
3

Python 2.7: 123 122 120 Bytes

probs masih dapat menyimpan beberapa 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

sunting1: N=abs(n)untuk menyimpan 1 byte

sunting2: (i+1)*(n>0)or-n-iuntuk menyimpan 2 byte

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

Mengembalikan matriks sebagai daftar daftar bilangan bulat, misalnya: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Bagaimana itu bekerja:

            [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
nimi
sumber
2

Perl, 175 byte

Termasuk 1 byte untuk -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;

;

(Ada baris baru tambahan yang saya tidak tahu bagaimana menunjukkannya dengan penurunan harga, tetapi Anda membutuhkannya).

Kebutuhan -pserta -M5.010atau -Euntuk menjalankan:

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

Sial, ini terlalu lama ... Saya akan mencoba beberapa pendekatan lain ketika saya punya waktu.

Dada
sumber
Mengapa Anda menggunakan eval?
Titus
@Titus Karena y///tidak menginterpolasi, jadi gunakan tanda kutip ganda untuk menginterpolasi $wdan $k, kemudian evaluntuk mengeksekusi 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]
Lynn
sumber
2

J, 29 26 byte

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

Pemakaian

   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

Penjelasan

i.Output kata kerja range [0, 1, ..., n-1]untuk positif ndan [n-1, n-2, ..., 0]negatif nyang berguna di sini.

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
mil
sumber
2

Mathematica, 78 byte

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

Penjelasan

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

Buat matriks awal: 1x1 jika aneh, 2x2 jika genap.

Range[Abs@#-1]

Buat daftar dari 1 hingga abs (input) - 1.

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

Pad array awal menggunakan daftar tersebut di atas.

... +1~Min~-#

Tambahkan 1 atau -input, mana yang lebih kecil.

Abs

Terapkan nilai absolut ke seluruh matriks.

JungHwan Min
sumber
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"
";}

jalankan bersama php -r '<code>

loop melalui baris dan kolom, mencetak nilai tergantung pada jarak mereka ke pusat.

  • $n=abs($z)+1: +1Menyimpan beberapa +1dan -1dalam ekspresi selanjutnya
  • loop pergi dari -$n+1(pra-kenaikan dalam kondisi!) ke $n-1( -abs($z)ke abs($z))
  • baris / kolom 0 (dan untuk ganjil $n: 1) dilewati
    ( $n&1apakah berlaku untuk kolom genap di sini! Ingat +1?)
  • Pencetakan untuk $ z positif juga mendapat manfaat dari +1.
Titus
sumber
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-)

Pemakaian:

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]

Terima kasih kepada nimi untuk 2 10 20 24 byte!

BlackCap
sumber
1
negateis (0-)
nimi
1
Anda dapat mengubah fke [id!id,tail!init]!!mod n 2dan kemudian inline ke gdan menggunakan 1<2penjaga untuk mengikat hasil tengah cabang: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Anda tidak perlu nama untuk fungsi utama.
nimi
1
Oh, Anda bisa inline ajuga (dan beralih kembali ke 1<2penjaga): 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
Yang terakhir untuk hari ini: m=map, di !: ...(++).m ydan g: 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)))

ladalah ukuran array. The n<0?-n-j:j+1tampaknya canggung tapi saya tidak dapat menemukan sesuatu yang lebih baik.

Neil
sumber
1

Vim, 152 143 byte

Saya yakin ini bisa lebih banyak bermain golf, terutama dua baris terakhir, tetapi otak saya digoreng.

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

Cobalah online!

Ini dia dalam format xxd dengan karakter yang tidak patut dicetak:

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

Penjelasan

Itu membangun piramida dari pusat ke luar, mengelilingi nomor pusat dengan xes:

x x x
x 5 x
x x x

Kemudian ia mengganti xes dengan angka berikutnya dan mengelilinginya dengan xes lagi:

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

...dan seterusnya. Untuk bilangan genap ia melakukan hal yang sama tetapi dimulai dengan basis 2x2.

Ini kodenya "ungolfed." Ini agak tidak konvensional di mana saya "merekam" makro dengan mengetikkannya ke dalam buffer (karenanya semuanya <C-v>) dan kemudian menghapusnya ke dalam register, yang merupakan cara terbaik yang saya temukan untuk membuat makro tanpa benar-benar mengeksekusi penekanan tombol.

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
Jordan
sumber
0

PHP, 215 Bytes

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;}
Jörg Hülsermann
sumber
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

Membutuhkan integer ndi ruang kerja, jika tidak dijalankan n=scan()untuk 8 byte tambahan.

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
Headcrash
sumber