Utwórz piramidalną matrycę

23

Macierz piramidalna to macierz kwadratowa, w której wszystkie liczby rosną lub maleją od punktu środkowego, podobnie jak dwie poniższe macierze:

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

Lub:

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

Biorąc pod uwagę niezerową liczbę całkowitą n, utwórz macierz piramidalną, w której liczby przechodzą od 1do nw porządku rosnącym (jeśli n <0) lub malejącym (jeśli n> 0) od środka. Jeśli njest parzysty, to będą 4 środkowe liczby (patrz przykłady).

Jak zawsze:

  • Opcjonalny format wejściowy i wyjściowy
    • Liczba spacji, separator itp. Jest opcjonalna

Przypadki testowe:

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
źródło
10
Dlaczego przypadek parzysty różni się od przypadku nieparzystego? Nie ma powodu, dla którego wszystkie matryce nie mogą być zgodne z tym samym wzorem.
Greg Martin
2
Ponieważ wejściem miała być długość ścianki bocznej, w którym to przypadku istnieje różnica między liczbą nieparzystą a parzystą. Zamiast tego zdecydowałem się na maksymalną wartość, ale utrzymałem tam nieparzystą i parzystą różnicę. To może wydawać się dziwne i może nie być dobrym wytłumaczeniem, ale jest to wyjaśnienie, dlaczego istnieje różnica. :-)
Stewie Griffin
2
Czy możemy założyć -10 < n < 10?
Tytus
2
Jest ok, jeśli nie wygląda na idealny kwadrat, o ile jest to numerycznie. Jeśli rzędy z wieloma dziesiątkami są szersze niż te z kilkoma dziesiątkami, to w porządku ...
Stewie Griffin

Odpowiedzi:

5

Galaretka , 18 17 bajtów

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

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

|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
źródło
7

EXCEL: 126 bajtów

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

Wypróbuj online *

Uwaga: w tej odpowiedzi używana jest notacja R1C1. Jeśli masz zamiar tego spróbować sam. musisz to włączyć w opcjach programu Excel.

podany wzór musi znajdować się w każdej komórce znajdującej się poza (2,2). Umieść żądaną wielkość piramidy w (1,1).

szybki zrzut ekranu formuły w akcji:
enter image description here

Oto dodatkowe zdjęcie dobrej zabawy z formatowaniem warunkowym!

* Obecnie aktualizacja zajmuje bardzo dużo czasu.


źródło
To nie obsługuje poprawnie przypadków ujemnych lub parzystych. Możesz także skrócić kod do =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)92 bajtów. Nadal nie obsługuje przypadków i formuły nie można przeciągać, ponieważ odwołanie do komórki nie jest zablokowane.
gtwebb
1
Więcej golfa te same problemy. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb
@gtwebb dzięki za poinformowanie mnie. Będę musiał naprawić
-1. To nie działa Nie obsługuje negatywnych danych wejściowych. Nie obsługuje nawet danych wejściowych. Jeśli wstawiasz tę formułę w każdej odpowiedniej komórce, potrzebujesz albo potrzebujesz Rangedużo więcej niż 126 bajtów.
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]

Sporządzać listę

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

i bawcie się z tym trochę.


edycja: nowy sposób tworzenia listy + dzięki Lynn za dwa bajty

pacholik
źródło
If n is even, then there will be 4 center numbers
Rod
@Rod Nie, nie będzie. Co sprawia, że ​​tak myślisz?
pacholik
3
to jedna z zasad
Rod
@Rod Oh. Kilka minut temu. Edytowany.
pacholik
2
Nie jest nowy, tylko nie wyróżniony: c
Rod
6

MATL , 26 24 bajtów

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

Wypróbuj online!Lub zweryfikuj wszystkie przypadki testowe (nieco zmodyfikowany kod, który ma służyć jako pakiet testowy).

Wyjaśnienie

Kod najpierw buduje tablicę wyjściową, przyjmując pozytywne dane wejściowe n. Tablica jest inicjalizowana jak 1dla nieparzystych danych wejściowych lub jako pusta tablica dla parzystych danych wejściowych (jest ona tworzona jako macierz tożsamości o wielkości równej parzystości danych wejściowych). Następnie powtarzane są nczasy dla parzystego wprowadzania i n-1czasy dla nieparzystego wprowadzania: rozszerz tablicę o ramkę zawierającą 0i dodaj 1do wszystkich elementów.

Na przykład kroki wprowadzania nsą następujące:

  • Tablica początkowa:

    1
    
  • Przedłuż z ramą:

    0 0 0
    0 1 0
    0 0 0
    
  • Dodaj 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Przedłuż z ramą:

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

Daje to prawidłowe wyjście dla dodatniego sygnału wejściowego. Jeśli dane wejściowe są ujemne, tablicę należy zmodyfikować, dodając wartość wejściową minus 1i przyjmując wartość bezwzględną:

    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

Możesz obserwować powiększanie się tablicy (zmodyfikowany kod, aby pokazać kroki pośrednie) na MATL Online! Tłumacz jest wciąż wersją beta. Jeśli to nie działa, naciśnij ponownie „Uruchom” lub ponownie załaduj stronę.

Skomentowany 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
Luis Mendo
źródło
Widzę, że ponownie użyłeś kodu z pytania dotyczącego animacji. Niesamowite! Zabawne jest to, że ten kod również wygrałby w tym pytaniu, nawet jeśli jest dłuższy niż inna wersja;).
Magic Octopus Urn
1
@ carusocomputing Tak, to jest podobne: duplikat, wyświetlanie, pauza 1 sekunda, wyraźne wyjście :-)
Luis Mendo
Również nie jestem pewien, dlaczego, ale wszelkie dane powyżej 14 zatrzymują się na 14. Anuluj to, jest to ograniczenie konsoli online „Upłynął limit czasu operacji”.
Magic Octopus Urn
@carusocomputing Błąd mówi „upłynął limit czasu operacji”. Wydaje mi się, że tłumaczowi zajmuje to zbyt długo. Spróbuj zmniejszyć przerwę, aby powiedzieć .2sekundy
Luis Mendo
@carusocomputing Tak, to czas oczekiwania na tłumacza online. Obecnie ograniczamy zadania do 30 sekund. Jak sugeruje Luis, możesz skrócić czas pauzy
Suever
3

Python 2.7: 123 122 120 bajtów

probs wciąż mogą zapisać kilka bajtów ...

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)aby zapisać 1 bajt

edit2: (i+1)*(n>0)or-n-iaby zapisać 2 bajty

Aaron
źródło
3

Haskell, 119 113 110 104 102 101 bajtów

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]

Zwraca macierz jako listę list liczb całkowitych, na przykład: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Jak to działa:

            [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
źródło
2

Perl, 175 bajtów

Zawiera 1 bajt dla -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;

;

(Jest ostatnia nowa linia, której nie wiem, jak pokazać z przeceną, ale jej potrzebujesz).

Potrzebuje, -pa także -M5.010lub -Euruchomić:

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

Cholera, to za długo ... Spróbuję innych podejść, kiedy będę miał trochę czasu.

Dada
źródło
Dlaczego używacie eval?
Tytus
@Titus Ponieważ y///nie interpolate, więc jest użyć cudzysłowia interpolować $wi $k, a następnie evalwykonać y///.
Dada
2

Python 2, 109 bajtów

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
źródło
2

J, 29 26 bajtów

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

Stosowanie

   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

Wyjaśnienie

Przydaje się i.czasownik zakresu [0, 1, ..., n-1]dla wartości dodatniej ni [n-1, n-2, ..., 0]ujemnej, nco jest przydatne tutaj.

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
mile
źródło
2

Mathematica, 78 bajtów

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

Wyjaśnienie

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

Wykonaj macierz początkową: 1x1, jeśli nieparzysta, 2x2, jeśli parzysta.

Range[Abs@#-1]

Wygeneruj listę od 1 do abs (wejście) - 1.

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

Wypełnij początkową tablicę za pomocą wyżej wymienionej listy.

... +1~Min~-#

Dodaj 1 lub - wejście, w zależności od tego, która wartość jest mniejsza.

Abs

Zastosuj wartość bezwzględną do całej macierzy.

JungHwan Min
źródło
1

PHP, 177 157 bajtów

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

Biegnij z php -r '<code>

zapętla się przez rzędy i kolumny, drukuje wartości w zależności od ich odległości od środka.

  • $n=abs($z)+1: +1Zapisuje kilka +1i-1 w późniejszych wyrażeniach
  • pętle przechodzą od -$n+1(wstępny przyrost warunku!) do $n-1( -abs($z)do abs($z))
  • wiersz / kolumna 0 (i dla nieparzystych $n: 1) są pomijane
    ( $n&1dotyczy to nawet parzystych kolumn! Pamiętasz +1?)
  • Drukowanie na dodatnie $ z również korzysta z +1.
Tytus
źródło
1

Haskell, 191 183 173 169 168 bajtów

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

Stosowanie:

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]

Podziękowania dla nich za 2 10 20 24 bajtów!

Gajówka
źródło
1
negatejest (0-)
nimi
1
Można zmienić f, aby [id!id,tail!init]!!mod n 2i następnie go do inline gi używać 1<2strażnika związać pośredni wynik oddziału: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Nie potrzebujesz nazwy dla głównej funkcji.
nimi
1
Oh, można wbudować ateż (i powrócić do 1<2strażnika) 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
Ostatnia na dzisiaj: m=mapw !: ...(++).m yi 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 bajtów

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

ljest rozmiarem tablicy. n<0?-n-j:j+1Wydaje się niezgrabny, ale nie mogę znaleźć nic lepszego.

Neil
źródło
1

Wigor, 152 143 bajty

Jestem pewien, że można by to bardziej zagrać w golfa, szczególnie te dwie ostatnie linie, ale mój mózg jest smażony.

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

Wypróbuj online!

Oto format xxd ze znakami niedrukowalnymi:

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

Wyjaśnienie

Buduje piramidę od środka, otaczając numer centralny xes:

x x x
x 5 x
x x x

Następnie zastępuje xes kolejnym numerem i ponownie otacza xes:

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

...i tak dalej. W przypadku liczb parzystych robi to samo, ale zaczyna się od podstawy 2x2.

Oto kod „nieprzygotowany”. Jest to nieco niekonwencjonalne, ponieważ „nagrywam” makro, wpisując je do bufora (stąd wszystkie litery <C-v>s), a następnie usuwając je z rejestru, co jest najlepszym sposobem, w jaki udało mi się skomponować makro bez faktycznego naciskania klawiszy.

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
Jordania
źródło
0

PHP, 215 bajtów

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
źródło
0

R, 112 bajtów

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

Potrzebuje liczby całkowitej nw obszarze roboczym, w przeciwnym razie uruchom n=scan()o dodatkowe 8 bajtów.

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
Zawód głowy
źródło