マトリックスのダイヤモンド化


20

マトリックスが与えられたら、左上の要素が上にあり、反対角線が中央の行で、右下の要素が下にあるマトリックスの表現を出力します。

たとえば、次のマトリックスを考えます。

1 2 3
4 5 6
7 8 9

このマトリックスのひし形バージョンは次のとおりです。

  1
 4 2
7 5 3
 8 6
  9

入力と出力

入力マトリックスは、リストのリスト(または選択した言語で類似したもの)として提供されます。出力はリストのリストでもあります。

行列には正の整数のみが含まれます。

入力行列は必ずしも正方形ではありません。

入力行列は少なくとも1×1です。

テストケース

Input:  [[1]]
Output: [[1]]

Input:  [[1,2],[3,4]]
Output: [[1],[3,2],[4]]

Input:  [[1,2,3],[4,5,6]]
Output: [[1],[4,2],[5,3],[6]]

Input:  [[11,2,5],[3,99,3],[4,8,15],[16,23,42]]
Output: [[11],[3,2],[4,99,5],[16,8,3],[23,15],[42]]

得点

これはであるため、バイト単位の最短回答が優先されます。



関連/一般化。(ただし、不規則な配列を許可し、45度の倍数の回転が必要であるため、これはだましとは見なされません。)
マーティンエンダー

回答:


19

J、7バイト

<@|./.

これは名前のない単項動詞で、行列を取り、対角線のリストを返します。

   input =. i.3 4
   input
0 1  2  3
4 5  6  7
8 9 10 11

   <@|./. input
┌─┬───┬─────┬─────┬────┬──┐
│0│4 1│8 5 2│9 6 3│10 7│11│
└─┴───┴─────┴─────┴────┴──┘

ここでテストしてください。

説明

  • /.各対角線に関数を適用するためのJの組み込みです。残念ながら、これらの対角線は、ここで欲しいものとは逆の順序で与えられます。
  • では<@|.、まず|.対角線を逆にして<からボックスに適用します(これはJの不規則な配列を返す唯一の方法です。通常の配列は常に長方形なので、対角線はゼロで埋められます)。

それはクレイジーで美しいです。私はいつかこの言語を学ぶのに時間をかけます。
憧れるマシン

5

Python、91バイト

e=enumerate
lambda M:[[r[n-i]for i,r in e(M)if-1<n-i<len(r)][::-1]for n,_ in e(M[1:]+M[0])]

Ideoneでテストします。


Python + NumPy、69バイト

import numpy
lambda M:map(M[::-1].diagonal,range(1-len(M),len(M[0])))

2D NumPy配列を入力として期待し、NumPy配列のリストを返します。Ideoneでテストします。


4

ゼリー、7バイト

ṚŒDṙZL$

オンラインでお試しください!

説明

Ṛ         Reverse the matrix vertically.
 ŒD       Get its diagonals. However these start from 
          the main diagonal, not the corners.
    ZL$   Get the width of the input matrix.
   ṙ      Rotate the list of diagonals left by that many 
          places to obtain the correct order.

Jellyはわかりませんが、ユニコードオペランドが必要な場合は7バイトではありません。
グイドボット

5
@Guidobot Jellyは、1バイトとして認識される256文字のそれぞれをエンコードするカスタムコードページを使用します。
デニス

4

Mathematica、58 56バイト

a=Length;Reverse@#~Diagonal~b~Table~{b,1-a@#,a@#&@@#-1}&

無名関数。ネストされた配列を受け取ります。


あなたがものを保存することができますLength[#]場所です\[Transpose]。そして、おそらくエイリアスから別のLength
Sp3000

またはLength@#&@@#、同じバイトカウントのASCIIのみ。
マーティンエンダー

3

CJam、17バイト

{eeSf.*::+W%zSf-}

スタック上の行列を期待し、その対角線で置き換える無名ブロック(関数)。

ここでテストしてください。

これ(Sp3000が発見)は、同じバイトカウントで機能します。

{_,,Sf*\.+W%zSf-}

説明

これは、例を使用して説明するのが最適です。入力を考慮してください:

[[0  1  2  3]
 [4  5  6  7]
 [8  9 10 11]]

ee    e# Enumerate matrix, turning each row [x ... z] into [i [x ... z]] where
      e# i is the vertical index from the top.

[[0 [0  1  2  3]]
 [1 [4  5  6  7]]
 [2 [8  9 10 11]]]

Sf.*  e# Replace each i with a string of i spaces.

[[""   [0  1  2  3]]
 [" "  [4  5  6  7]]
 ["  " [8  9 10 11]]]

::+   e# Prepend these strings to the rows.

[[0  1  2  3]
 ['  4  5  6  7]
 ['  '  8  9 10 11]]   e# Note that each '  corresponds to a space character.

W%    e# Reverse the rows.

[['  '  8  9 10 11]
 ['  4  5  6  7]
 [0  1  2  3]]

z     e# Zip/transpose.

[[ '  '  0]
 [ '  4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

Sf-   e# Remove spaces from each row.

[[ 0]
 [ 4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

3

Python 2、88 87バイト

lambda L:[filter(None,x)[::-1]for x in map(None,[],*[i*[0]+r for i,r in enumerate(L)])]

0を先頭に追加し、圧縮してから、偽の要素を削除します。タプルのリストを返します。これはmap(None,...)zip_longest (欠落しているスポットをで埋めるNone)を実行filter(None,...)し、偽の要素を削除するために使用します。

面倒なことに、1行1列の行列ではなくタプルのリストが返される[]ように、行に追加の行を追加する必要があります。ただし、余分な行は削除されます。mapmap(None,*[[1]])[1][(1,)]filter

(-1バイトの@Dennisに感謝)


3

ルビー、68 66バイト

匿名関数。

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • スプラット演算子の仕組みにより、配列の追加を省略することで2バイトを節約することができました。

2

Mathematica、60バイト

#&@@@#&/@GatherBy[Join@@MapIndexed[List,#,{2}],Tr@*Last]&

where は、Mathematicaが後置\[Transpose]演算子として読み取るUnicode文字です。

これは他のMathematicaソリューションよりも少し長いですが、Diagonalsビルトインを使用せず、まったく異なるアプローチを使用しているため、投稿したいと思いました。

説明

MapIndexed[List,#,{2}]

これにより、最初にマトリックスが転置されます(マトリックスが平坦化された場合に、対角線が正しい順序で表示されるようになります)。その後、我々は、マップListの各行列要素を回転させるインデックスと共にマトリックスのセル上i{i, {x, y}}場所xy行列の要素の座標です。

Join@@...

これにより、最も外側の次元が平坦化されるため、列要素の順序でマトリックス要素(および座標)のフラットリストが作成されます。

GatherBy[..., Tr@*Last]

これは、それらの要素を座標の合計でグループ化します。対角線は定数の線であることに注意してくださいx+y。したがって、これは必要なグループ化を正確に行います。各グループ内の順序は保持されます。ここで、座標を削除する必要があります。これはかなり不可解な方法で行われます:

#&@@@#&/@...

これは、#&@@@#&各グループに関数をマッピングします。それ自体 #&グループ内の各要素に適用され、#単に最初の引数、つまり元の行列要素です。


理由についての説明\[transpose]
致命的な

1
このコードポイントとそれが私的利用のUnicodeコードポイントだ@Fatalize、およびグリフMathematicaの仲間上付き文字であるTreference.wolfram.com/language/ref/character/Transpose.htmlは ... \[Transpose]単にそのUnicode文字のASCIIの音訳です。Unicode文字または音訳のいずれかをMathematicaにコピーできます。
マーティンエンダー

2

オクターブ、77バイト

accumarray関数の少しの乱用:

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

これは、匿名関数を定義します。使用するには、変数に割り当てるかを使用しますans

入力は、:行セパレータとしてのマトリックスです。出力は、各行の配列を含むセル配列です(Octaveはギザギザの配列に相当)。これはOctaveによって表示され、セル配列のインデックスと各セルの内容が表示されます。ここで試してみてください

スペースと改行のみで区切られた結果を表示するには:83バイト

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

こちらから試すことができます


2

JavaScript(Firefox)、86 75バイト

a=>a.concat(a[0]).slice(1).map((_,i)=>[for(v of a)if(n=v[i--])n].reverse())

@Neilのおかげで11バイト節約されました!

Firefox 30以降で動作します。配列の配列を取ります。


良いアルゴリズムですがa.concat(a[0]).slice(1)、正しい長さの配列を取得するために使用できます。また、[for(of)]ES6 ではありません。私は通常、(Firefox 30+)などと書いています。
ニール

うわー@Neil、私は少し愚か使用することを考え出すない感じconcatslice。ありがとう!
-user81655

2

オクターブ、63 62バイト

@DonMueのおかげで1バイト削除されました... @LuisMendo!

@(a)cellfun(@(x)x(x>0)',num2cell(spdiags(flipud(a)),1),'un',0)

私は退屈なルートに行き、対角線をはみ出しました。

ideoneでのサンプル実行。


短く'uni'することができると思う'un'
ルイスメンドー

@LuisMendoええ、そうです!ありがとう!:)
ビーカー

2

Haskell、83 82バイト

r=zip[0..]
\o->fst$span(any(>0))[reverse[e|(x,t)<-r o,(v,e)<-r t,x+v==a]|a<-[0..]]

nimiがバイトを保存しました。ありがとう!


1

Python、128バイト(numpy)

(lambda A: (lambda A,S:[[A[U][I-U] for U in range(min(S[1]-1,I),max(I-S[0]+1,0)-1,-1)] for I in range(S[1]+S[0]-1)])(A,A.shape))

プログラミングパズルとコードゴルフへようこそ!デフォルトでは、ゴルフチャレンジのコードへの提出はプログラムまたは機能であり、I / Oに対して承認された方法の 1つを使用する必要があります。ハードコードされた変数への入力を予期するスニペットは許可されていません。
デニス

使用lambdaする最初のソリューションを、提出として使用できるラムダのみに再加工できるようです。
アレックスA.

私はそれをラムダ
ルイスMasuelli

lambda A:[[A[U][I-U]for U in range(max(I-len(A)+1,0),min(len(A[0])-1,I)+1)]for I in range(len(A+A[0])-1)](元のリビジョンのように)少し短くなります。また、質問からオリエンテーションを取得するにはに変更A[U][I-U]する必要がありますA[I-U][U]
デニス

家に帰ったらチェックします。理にかなっています
ルイスMasuelli

1

Pyth41 17バイト

tm_<dx+dYk.T+LaYk

オンラインでお試しください!

@Doorknobの別の問題に対する解決策に触発されました。

使い方:

tm_<dx+dYk.T+LaYk
            +L      prepend to each subarray...
              aYk   (Y += ''). Y is initialized to [],
                    so this prepends [''] to the first
                    subarray, ['', ''] to the second, etc.
                    ['' 1  2  3
                     '' '' 4  5  6
                     '' '' '' 7  8  9
                     '' '' '' '' 10 11 12
                     '' '' '' '' '' 13 14 15]
          .T        transpose, giving us
                    ['' '' '' '' ''
                     1  '' '' '' ''
                     2  4  '' '' ''
                     3  5  7  '' ''
                     6  8  10 ''
                     9  11 13
                     12 14
                     15]
 m_<dx+dYk          removes all empty strings in the
                    subarrays while reversing each one
t                   remove the first subarray

以前の試み:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK

オンラインでお試しください!

使い方:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK    input array stored as Q
JlQ                                          J = len(Q)
   KlhQ                                      K = len(Q[0])
       m                            Ut+JK    list for d from 0 to J+K-1:
        _m       }AAAAAAAAAABBBBBBBB             reversed list for k from A to B, where:
                  h.MZ,0-dtK                       A = max(0, d-(K-1))
                       0-dtK                               0  d-(K-1)
                            h.mb,tJd               B = min(J-1, d)
                                 tJd                       J-1  d
          @@Qk-dk                                    Q[k][d-k]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.