Bir piramidal matris oluşturun


23

Bir piramidal matris, aşağıdaki iki matris gibi, tüm sayıların merkez noktadan arttığı veya azaldığı kare bir matristir:

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

Veya:

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

Sıfır olmayan bir tamsayıdır verilen nnumaraları gider burada, piramit şeklinde bir matris oluşturmak 1için nartan sırada ya (eğer n merkezi <0), ya da azaltılması düzeni (eğer n> 0). Eğer neşitse, 4 orta sayı olacaktır (örneklere bakınız).

Her zamanki gibi:

  • İsteğe bağlı giriş ve çıkış formatı
    • Boşluk sayısı, sınırlayıcı vs. isteğe bağlıdır

Test durumları:

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
Çift dava neden tek davadan farklı? Matrislerin hepsinin aynı modeli izleyememesinin bir nedeni yoktur.
Greg Martin

2
Çünkü girişin yan duvarın uzunluğu olması gerekiyordu, bu durumda tek ve çift arasında bir fark vardı. Bunun yerine maksimum değere gitmeye karar verdim, ancak tek ve hatta farkı orada tuttu. Tuhaf görünebilir ve iyi bir açıklama olmayabilir, ancak neden bir farkın olduğunun açıklaması . :-)
Stewie Griffin,

2
Farz edebilir miyiz -10 < n < 10?
Titus,

2
Tamamen bir kare gibi görünmüyorsa , sayısal olarak konuşulduğu sürece sorun yok. 10'lu yılların satırları daha genişse, 10'luların sayısı 10 olanların ...
Stewie Griffin

Yanıtlar:


5

Jöle , 18 17 bayt

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

Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

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

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

Çevrimiçi deneyin *

Not: Bu cevap R1C1 Notasyonu kullanır. Eğer bunu kendin deneyeceksin. Excel seçeneklerinde bunu açmanız gerekir.

Verilen formülün ötesinde bulunan her hücrede bulunması gerekir (2,2). İstediğiniz piramit boyutunu (1,1) yerleştirin.

formülün hızlı ekran kapağı çalışırken:
görüntü tanımını buraya girin

İşte bir olan koşullu biçimlendirme ile bazı eğlenceli ek resim!

* Güncellemenin yapılması şu anda çok uzun zaman alıyor.


Bu, olumsuz durumları veya eşit durumları düzgün bir şekilde ele almaz. Ayrıca =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)92 bayt olan kodu kısaltabilirsiniz . Yine de vakalarla ilgilenmiyor ve hücre başvurusu kilitlenmediğinden formül sürüklenemiyor.
gtwebb 22:16

1
Yine de daha fazla golf aynı sorunları. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb

@gtwebb bana söylediğin için teşekkürler. Düzeltmem gerekecek

-1. Bu işe yaramıyor. Negatif girişi işlemez. Giriş bile yapmıyor. Bu formülü uygulanabilir her hücreye koyuyorsanız, ya bir Rangeya da 126 bayttan daha fazlasına ihtiyacınız vardır.
AdmBorkBork 23:16

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]

Liste oluştur

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

ve biraz onunla oynamak.


düzenleme: liste oluşturmak için yeni bir yol + iki bayt için thx Lynn


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

@Rod Hayır olmaz. Seni böyle düşündüren ne?
pacholik

3
bu kurallardan biridir
Rod

@Rod Oh. Sadece birkaç dakika önce. Düzenlenen.
pacholik

2
Yeni değil, sadece vurgulanmamış: c
Rod

6

MATL , 26 24 bayt

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

Çevrimiçi deneyin!Veya tüm test durumlarını doğrulayın (test paketi olarak kullanılmak üzere biraz değiştirilmiş kod).

açıklama

Kod önce pozitif girdiyi varsayarak çıktı dizisini oluşturur n. Dizi 1tek giriş için olduğu gibi veya çift giriş için boş bir dizi olarak başlatılır (bu, girişin paritesine eşit boyutta bir kimlik matrisi olarak oluşturulur). Daha sonra, aşağıdakiler çift ​​giriş için defa ve tek giriş niçin defalarca tekrarlanır n-1: diziyi içeren bir çerçeve ile genişletin 0ve 1tüm öğelere ekleyin .

Örneğin, giriş için adımlar nşunlardır:

  • İlk dizi:

    1
    
  • Çerçeveyle genişlet:

    0 0 0
    0 1 0
    0 0 0
    
  • Ekle 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Çerçeveyle genişlet:

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

Bu, pozitif giriş için doğru çıkışı verir. Giriş negatifse, dizinin giriş eksi ekleyerek 1ve mutlak değeri alarak değiştirilmesi gerekir :

    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

Dizinin büyümesini izleyebilir (ara adımları gösterecek şekilde değiştirilmiş kod) MATL Online'da izleyebilirsiniz! Tercüman hala bir beta. Çalışmazsa, "Çalıştır" düğmesine tekrar basın veya sayfayı yeniden yükleyin.

Yorumlanan kod

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

Görüyorum ki animasyon sorusundaki kodu tekrar kullandın. Müthiş! Komik olan kısım, bu kodun diğer versiyonunuzdan daha uzun olsa bile, yine de bu soruda kazanacağıdır;).
Magic Octopus Urn

1
@carusocomputing Evet, benzer: yinelenen, görüntüleme, 1 saniye duraklatma, çıktıyı netleştirme :-)
Luis Mendo

Ayrıca, neden olduğundan emin değilsiniz, ancak 14'ten büyük herhangi bir giriş 14'te durur. Bunu iptal et, çevrimiçi çalışma "zaman aşımına uğradı" konsolu için bir sınırlama.
Magic Octopus Urn

@ carusocomputing Hata "işlem zaman aşımı" diyor. Tercüman için çok uzun sürüyor sanırım. Duraklatmayı .2saniye söylemeyi azaltmayı
Luis Mendo

@carusocomputing Evet, çevrimiçi tercümandaki zaman aşımı süresidir. Şu anda işleri 30 saniye ile sınırlıyoruz. Luis'in önerdiği gibi, duraklama süresini azaltabilirsiniz
Suever

3

Python 2.7: 123 122 120 Bayt

Probs hala birkaç bayt kurtarabilir ...

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 bayt kaydetmek

edit2: (i+1)*(n>0)or-n-i2 bayt kaydetmek için


3

Haskell, 119 113 110 104 102 101 bayt

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]

Matrisi, tam sayı listelerinin bir listesi olarak döndürür, örneğin: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Nasıl çalışır:

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

İçin 1 bayt içerir -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;

;

(İşaretleme ile nasıl gösterileceğimi bilmediğim son bir yeni satır var, ama buna ihtiyacınız var).

İhtiyaçlar -psıra sıra -M5.010veya -Eçalıştırmak için:

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

Kahretsin, bu çok uzun ... Biraz zamanım varken başka yaklaşımlar deneyeceğim.


Neden kullanabilirim eval?
Titus,

@Titus Çünkü y///enterpolasyon yapmaz, enterpolasyon yapmak $wve $ksonra evalçalıştırmak için çift tırnak kullanmaktır y///.
Dada

2

Python 2, 109 bayt

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 bayt

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

kullanım

   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

açıklama

Aralık i.fiili , burada yararlı olan [0, 1, ..., n-1]pozitif nve [n-1, n-2, ..., 0]negatif için çıktı verir 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 bayt

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

açıklama

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

Başlangıç ​​matrisini yapın: tek ise 1x1, çift ise 2x2.

Range[Abs@#-1]

1'den abs (giriş) - 1'e kadar bir liste oluşturun.

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

Yukarıda belirtilen listeyi kullanarak ilk diziyi tuşlayın.

... +1~Min~-#

Hangisi daha küçükse, 1 veya -putu ekleyin.

Abs

Matrisin tamamına mutlak değer uygulayın.


1

PHP, 177 157 bayt

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

koşmak php -r '<code>

Satırlar ve sütunlar arasında dolaşır, merkeze uzaklıklarına bağlı olarak değerleri yazdırır.

  • $n=abs($z)+1: +1Birkaç kurtarıyor+1 ve -1sonraki ifadelerde
  • döngüler -$n+1(koşulda artış öncesi!) ila $n-1(-abs($z) ila abs($z))
  • satır / sütun 0 (ve tek $n: 1 için) atlanır
    ($n&1 burada bile sütunlar için geçerlidir unutmayın! +1?)
  • Pozitif $ z için baskı da yararlanır +1.

1

Haskell, 191 183 173 169 168 bayt

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

Kullanımı:

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]

2 10 20 24 bayt için nimi sayesinde !


1
negateis (0-)
nimi 22:16

1
Değişebilirsin fiçin [id!id,tail!init]!!mod n 2ve ardından yerinde içine gve kullanımı 1<2şube orta seviyedeki bir sonucunu bağlamak bekçi: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Ana işlev için bir isme ihtiyacınız yoktur.
nimi,

1
Oh, satır içine alabilirsiniz ada (ve geri dönmek 1<2bekçi): 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
: Son bugün için bir m=mapyer, !: ...(++).m yve 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 bayt

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

ldizinin boyutu. n<0?-n-j:j+1Garip görünüyor ama ben daha iyi bir şey bulamıyorum.


1

Vim, 152 143 bayt

Eminim bu daha çok golf oynayabilir, özellikle de son iki satır, ama beynim yandı.

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

Çevrimiçi deneyin!

İşte yazdırılamayan karakterlerle xxd formatında:

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

açıklama

Piramidi merkezden dışarıya çevirir, merkez numarasını xes ile sayar:

x x x
x 5 x
x x x

Sonra esleri bir xsonraki sayı ile değiştirir ve tekrar es ile çevreler x:

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

...ve bunun gibi. Çift sayılar için aynı şeyi yapar ancak 2x2 tabanla başlar.

İşte "ungolfed" kodu. Bu biraz alışılmadık bir makroyu ara belleğe yazarak (dolayısıyla tüm <C-v>s) yazıp "sicile kaydetmem" ve sonra bir kayıt defterine silmem, ki bu aslında tuş vuruşlarını uygulamadan bir makro oluşturmanın en iyi yolu.

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 Bayt

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 bayt

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Çalışma alanındaki tamsayıya ihtiyaç duyuyor, aksi takdirde n=scan()fazladan 8 bayt için çalışıyor.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.