ピラミッド型マトリックスを作成する


23

ピラミッド型マトリックスは、以下の2つのマトリックスのように、すべての数値が中心点から増減する正方マトリックスです。

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昇順のいずれか(もしN中心から<0)、または降順は(もしN> 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
数値的に言えば、完璧な正方形に見えなくても問題ありません。多くの10Sを持つ行は大丈夫だ、数十...と、これらのことより広くしている場合
Stewieグリフィン

回答:


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

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]

リストを作成

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

少し遊んでみてください。


編集:リストを作成する新しい方法+ 2バイトのthx Lynn


If n is even, then there will be 4 center numbers
ロッド

@ロッドいいえ、ありません。何があなたをそう思わせますか?
パチョリク

3
これは、ルールの一つである
ロッド

@ロッドああ。ほんの数分前。編集済み。
パチョリク

2
それはちょうど強調されていない、新しいものではありません:C
ロッド

6

MATL26 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

アニメーションの質問のコードを再利用したようです。驚くばかり!おもしろいのは、このコードは他のバージョンよりも長いにもかかわらず、その質問でも勝つということです;)。
魔法のタコUr

1
@carusocomputingはい、似ています:複製、表示、1秒の一時停止、出力のクリア:-)
ルイスメンドー

また、理由はわかりませんが、14を超える入力は14で停止します。キャンセルするのは、オンラインコンソールの「操作がタイムアウトしました」という制限です。
魔法のタコUr

@carusocomputingエラーには「操作がタイムアウトしました」と表示されます。通訳には時間がかかりすぎると思います。を言うためにポーズを減らして.2
ルイスメンドー

@carusocomputingはい、これはオンラインインタープリターのタイムアウトです。現在、ジョブは30秒に制限されています。ルイスが示唆するように、一時停止時間を減らすことができます
Suever

3

Python 2.7: 123 122 120バイト

probsはまだ数バイトを節約できます...

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-i2バイトを保存します


3

ハスケル、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$kevalを実行し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

Mathematica、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からabs(input)-1までのリストを生成します。

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

前述のリストを使用して初期配列にパディングします。

... +1~Min~-#

1または-inputの小さい方を追加します。

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)to abs($z))へ
  • 行/列0(と奇数のために$n:1)をスキップしているが
    $n&1ここでは偶数列についても同様です忘れないでください!+1?)
  • 正の$ zの印刷もから恩恵を受け+1ます。

1

ハスケル、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バイトのnimiに感謝します!


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。メイン関数の名前は必要ありません。
nimi

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

1
今日の最後のもの:m=map!...(++).m yおよびgg 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バイト

(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

Vim、152 143バイト

特に最後の2行はこれでもっとゴルフできると確信していますが、私の脳は揚げられています。

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を次の番号に置き換え、esで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

...等々。偶数の場合、同じことを行いますが、2x2ベースで始まります。

コードは「ungolfed」です。マクロをバッファに入力して(したがってすべての<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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.