Створіть пірамідальну матрицю


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або в порядку зростання (якщо п <0), або зменшенням (якщо п> 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
Тому що вхід повинен був бути довжиною бічної стінки, і в цьому випадку є різниця між непарною і парною. Я вирішив замість цього досягти максимального значення, але втримав там непарну і рівну різницю. Це може здатися дивним і може не бути хорошим поясненням, але це пояснення, чому є різниця. :-)
Стюі Гріффін

2
Чи можемо ми припустити -10 < n < 10?
Тіт

2
Це нормально , якщо він не виглядати як ідеальний квадрат, до тих пір , як він це один чисельно кажучи. Якщо рядки з багатьма десятками ширші, ніж ті, у кого 10, то це нормально ...
Стюі Гріффін

Відповіді:


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 байт.
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
це одне з правил
стрижень

@ Род О. Всього кілька хвилин тому. Відредаговано.
pacholik

2
Це не нове, просто не виділено: c
пн

6

MATL , 26 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 секунда, чіткий вихід :-)
Луїс Мендо

Крім того, не впевнений, чому, але будь-який вхід вище 14 зупиняється на 14. Скасувати це, це обмеження онлайн-консолі "Операція вичерпана".
Чарівна восьминога урна

@carusocomputing Помилка говорить "час очікування роботи". Я думаю, що для перекладача це забирає занадто багато часу. Спробуйте зменшити паузу, щоб сказати .2секунди
Луїс Мендо

@carusocomputing Так, цей час закінчився в Інтернеті. Наразі ми обмежуємо завдання на 30 секунд. Як пропонує Луїс, ви можете зменшити час паузи
Suever

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 Оскільки y///не інтерполюється, то використовуйте подвійні лапки для інтерполяції, $wа $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

Математика, 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 до абс (вхід) - 1.

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

Прокладіть початковий масив, використовуючи вищезгаданий список.

... +1~Min~-#

Додайте 1 або -вхід, залежно від того, що менше.

Abs

Застосувати абсолютне значення до всієї матриці.


1

PHP, 177 157 байт

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]

Дякуємо німі за 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. Вам не потрібно ім’я для основної функції.
німі

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].
німі

1
Останній один на сьогодні: m=mapв !: ...(++).m yі 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].
німі

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

Вим, 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

Потім він замінює xes на наступне число і оточує його 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.