マトリックスを畳む!


13

行列が与えられたら、その値を上/下または左/右に合計してXを形成し、それを畳んでリストを返します。ここでアルゴリズムを説明します。

アルゴリズム

入力は、言語の適切な数値容量内の整数の奇数サイズの正方行列になります。

例として次のマトリックスを見てみましょう。

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

まず、メインの対角線または対角線上にある最も近い数字にすべての数字を追加します。つまり、マトリックスを対角線と対角線に沿って4つのセクションに分割し、各セクションのすべての数値を中央に向かって合計します。

1   2   3   2   1
    ↓   ↓   ↓    
0 → 3   2   3 ← 0
        ↓        
4 → 2 → 5 ← 6 ← 3
        ↑        
7 → 4   7   9 ← 4
    ↑   ↑   ↑    
0   6   7   2   5

この手順により、次の結果が得られます。

1        1
  5    5
    39
  17  15
0        5

次に、Xを平坦化し、左上を最初に、左下を最後に要素を織り交ぜて折ります。これにより、次の結果が得られます。

1, 0, 5, 17, 39, 5, 15, 1, 5

これは、メインの対角線を引き伸ばして反時計回りに回転させると想像できます。

これが最終結果です。

チャレンジ

このアルゴリズムを実装します。標準の抜け穴が適用されます。すべての妥当なI / O形式が受け入れられます。

テストケース

Input
Output

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

1, 0, 5, 17, 39, 5, 15, 1, 5

1 2 3 4 5
5 4 3 2 1
1 3 5 7 9
0 9 8 7 6
6 7 8 9 0

1, 6, 11, 16, 47, 7, 22, 5, 0

1 3 7 4 8 5 3
8 4 7 5 3 8 0
0 6 3 6 9 8 4
2 6 5 8 7 4 2
0 6 4 3 2 7 5
0 6 7 8 5 7 4
8 5 3 2 6 7 9

1, 8, 15, 11, 23, 20, 62, 32, 25, 13, 18, 3, 9

「5×5ではない」マトリックステストケースを追加できますか?
完全に人間の

1
@icrieverytimここに行く
HyperNeutrino

回答:


7

JavaScript、113バイト

s=>(l=s.length-1,a=[],s.map((v,y)=>v.map((n,x)=>a[q=2*[x,y,l-y].sort((u,v)=>u-v)[1]+(y>l/2),q-=q>l]=~~a[q]+n)),a)


うーん、なぜ~~?それらは互いに中和するので、それらの必要はありません。
ケビンCruijssen

2
@KevinCruijssen ~~undefined==0、だからこれはよりゴルファーです(a[q]||0)
ニール

@Neil Ah、については考えていませんでしたundefinedtshが使用したテストケースをコピーすると、がなくても機能することがわかりまし~~。そして、互いに中和しているの~~xと似ている-(-x)ので、偶然にそこに置かれたと思いました。修正していただきありがとうございます。
ケビンCruijssen

5

ゼリー25 23 21バイト

AṂ×ṠṚ
LHŒRṗ2Ç€ḅLĠịFS€

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

代替バージョン、19バイト

AṂ×ṠṚ
LHŒRṗ2Ç€ĠịFS€

Ġネストされた配列に対して不適切に動作したため、これは機能しませんでした。唯一の違いは、「仕組み」で説明したペア[q、p]が、ソートの前にp + nqにマッピングするのではなく、辞書式にソートされることです。

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

バックグラウンド

まず、要素を座標に置き換え、左方向および下方向に増やして、マトリックスの中心に(0、0)を配置します。

7x7行列Mの場合、次の座標を取得します。

(-3,-3) (-3,-2) (-3,-1) (-3, 0) (-3, 1) (-3, 2) (-3, 3)
(-2,-3) (-2,-2) (-2,-1) (-2, 0) (-2, 1) (-2, 2) (-2, 3)
(-1,-3) (-1,-2) (-1,-1) (-1, 0) (-1, 1) (-1, 2) (-1, 3)
( 0,-3) ( 0,-2) ( 0,-1) ( 0, 0) ( 0, 1) ( 0, 2) ( 0, 3)
( 1,-3) ( 1,-2) ( 1,-1) ( 1, 0) ( 1, 1) ( 1, 2) ( 1, 3)
( 2,-3) ( 2,-2) ( 2,-1) ( 2, 0) ( 2, 1) ( 2, 2) ( 2, 3)
( 3,-3) ( 3,-2) ( 3,-1) ( 3, 0) ( 3, 1) ( 3, 2) ( 3, 3)

次に、各座標ペアの最小絶対値を計算し、両方の座標の符号に乗算し、(i、j)(sign(i)m、sign(j)m)にマッピングします。ここで、m = min(| i | 、| j |)

(-3,-3) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-3, 3)
(-2,-2) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-2, 2)
(-1,-1) (-1,-1) (-1,-1) ( 0, 0) (-1, 1) (-1, 1) (-1, 1)
( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0)
( 1,-1) ( 1,-1) ( 1,-1) ( 0, 0) ( 1, 1) ( 1, 1) ( 1, 1)
( 2,-2) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 2, 2)
( 3,-3) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 3, 3)

同じペアに対応する行列要素を合計する必要があります。合計の順序を決定するために、各ペア(p、q)p + nqにマッピングします。ここで、nMの行/列の数です。

-24 -16  -8   0   6  12  18
-16 -16  -8   0   6  12  12
 -8  -8  -8   0   6   6   6
  0   0   0   0   0   0   0
 -6  -6  -6   0   8   8   8
-12 -12  -6   0   8  16  16
-18 -12  -6   0   8  16  24

合計の順序は、被加算数に対応する整数の順序に対応します。

使い方

LHŒRṗ2Ç€ḅLĠịFS€  Main link. Argument: M (matrix)

L                Compute n, the length (number of rows) of M.
 H               Halve it.
  ŒR             Symmetric range; map t to [-int(t), ..., 0, int(t)].
    ṗ2           Compute the second Cartesian power, yielding all pairs [i, j]
                 with -t ≤ i, j ≤ t.
      ǀ         Map the helper link over the resulting array of pairs.
         L       Yield n.
        ḅ        Unbase; map each pair [q, p] to (p + nq).
          Ġ      Group the indices of the resulting array of n² integers by their
                 corresponding values, ordering the groups by the values.
            F    Flatten M.
           ị     Index into the serialized matrix.
             S€  Compute the sum of each group.


AṂ×ṠṚ            Helper link. Argument: [i, j] (index pair)

A                Absolute value; yield [|i|, |j|].
 Ṃ               Minimum; yield m := min(|i|, |j|).
   Ṡ             Sign; yield [sign(i), sign(j)].
  ×              Multiply; yield [p, q] := [sign(i)m, sign(j)m].
    Ṛ            Reverse; yield [q, p].

5
これは素晴らしいです。
ウリエル



2

APL(ダイアログ)、60バイト*

同僚のマーシャルと共同で

匿名プレフィックスラムダ。引数として行列を取り、ベクトルを返します。想定している⎕IO (I NDEX OはゼロであることをRIGIN)、多くのシステムではデフォルトです。

{(,⍉{+/,(s×-×⍺)↓⍵×i∊¨⍨s←⌊⊃r÷2}⌺r⊢⍵)/⍨,(⊢∨⌽)=/¨i←⍳r←⍴⍵}

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

{} 匿名ラムダ; は右の引数です(ギリシャ語のアルファベットの右端の文字として):

⍴⍵ 引数の形状(2つの同一の要素のリスト)

r← として保存rr hoのように)

そのサイズの配列の すべてのɩndices、すなわち(0 0)(0 1)

i← 保管ii otaのように)

=/¨ 座標が等しいブール値(つまり、対角線)

() この匿名の暗黙の接頭辞関数を適用します。

   引数を逆にする

  ⊢∨ または、変更されていない引数を使用する

, ravel(単純なリストに直線化)

 これで、対角線のブールマスクができました。

(…これを)/⍨ 使用して、以下をフィルタリングします。

  ⊢⍵r引数を (から分離するために)生成する

  {}⌺r 各要素で次の匿名インrフィックスラムダを呼び出します。右引数()として-neighbourhood(必要に応じてゼロが埋め込まれます)、および行と列が埋め込まれた数値の2要素リスト(下/右が負、なしがゼロ)左引数として():

   r÷2r2で 割る

    最初の要素を選択します(それらは同一です)

    それを床に

   s← として保存ss hape 場合)

   i∊⍨¨ の各要素に対してi、ブールif sがそのメンバーである場合

   ⍵× 近所にそれを掛ける

   ()↓ 次の数の行と列をドロップします(下/右が負の値)。

    ×⍺ 左引数の符号(つまり、パディングの方向)

    - 否定する

    sそれを 掛ける

   , ravel(リストにまっすぐに)

   +/ 合計(プラス削減)

これで合計の完全なマトリックスができましたが、列ごとに読み取ったすべての値をフィルター処理する必要があります。

   転置

  , ravel(単純なリストに直線化)


* としてカウントし⎕U233A ます。オンラインでお試しください!

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