ジグザジフ行列


43

JPEG標準は、圧縮アルゴリズムの一部として、交互の方向の対角線に沿って行列を展開してベクトルにします。

ここに画像の説明を入力してください

あなたのタスクは、マトリックス(必ずしも正方形ではない)を取り、展開された形で返すことです。例として:

[1 2 3 4
 5 6 7 8
 9 1 2 3]

降るべきです

[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]

ルール

行列要素はより小さい正の整数であると仮定でき10ます。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

入力マトリックスは、便利で曖昧さのないネストされたリストまたは文字列形式で、または両方のマトリックス次元と共にフラットリストとして指定できます。(または、もちろん、あなたの言語がそれらを持っているなら、マトリックス型として。)

出力ベクトルは、任意の便利で明確なフラットリストまたは文字列形式にすることができます。

標準の規則が適用されます。

テストケース

[[1]]                                               => [1]
[[1 2] [3 1]]                                       => [1 2 3 1]
[[1 2 3 1]]                                         => [1 2 3 1]
[[1 2 3] [5 6 4] [9 7 8] [1 2 3]]                   => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 3 4] [5 6 7 8] [9 1 2 3]]                     => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 6 3 1 2] [5 9 4 7 8 3]]                       => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 5 9 6 3 4 7 1 2 8 3]]                         => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1] [2] [5] [9] [6] [3] [4] [7] [1] [2] [8] [3]]   => [1 2 5 9 6 3 4 7 1 2 8 3]

関連する課題


1
入力をJの実際の行列にすることはできますか?または、関数の一部として、ネストされたリストからマトリックスに変換する必要がありますか?
ガレス

4
マトリックスを2D配列として使用する場合、次元を入力として使用できますか?
-xnor

1
@Garethはい、行列型を入力として使用できます。
マーティンエンダー

1
@xnorうーん、それは少しトリッキーです。その量の冗長な情報を入力の前処理に少し取り入れたいと思います。
マーティンエンダー

それが言語のネイティブの順序である場合、フラットリストを優先の順序にすることはできますか?
ルイスメンドー

回答:


27

J、31 30 14 12 11バイト

[:;<@|.`</.

Ych。大きすぎる。

入力として行列を受け取ります。

説明

ここでJには利点があります。斜めの線を順番に取り、それらに動詞を適用する、oblique/.)と呼ばれるコマンドがあります。この場合、動名詞を使用して2つの動詞を交互に適用しています:<box)および<@|.reverse and box)。次に、;raze)を使用してすべてのボックス化を解除します。


26
Jは、それを理解するために英語の高度な学位が必要だと感じさせる唯一の言語です。
アレックスA.

2
@AlexA。ところで、「コマンド」という単語は「副詞」である必要がありました。
アダム

11

Pyth、24 23 21 20 19 18 17バイト

ssm_W=!Td.T+LaYkQ

代替17バイトバージョン: ssuL_G=!T.T+LaYkQ

                Q  input
           +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  1  2  3]
         .T        transpose, giving us
                   ['' '' ''
                    1  '' ''
                    2  5  ''
                    3  6  9
                    4  7  1
                    8  2
                    3]
  m_W=!Td          black magic
 s                 join subarrays together
s                  join *everything* on empty string (which means ''s used for
                     padding disappear)

おかげ@FryAmTheEggmanバイトのため、@Jakube 2バイトのため、および@isaacgバイトのために!

上記に暗示された「ブラックマジック」の説明:m_W=!Td本質的にすべての他のサブアレイを反転します。これは_W=!T、各サブアレイにマッピングすることによりこれを行います。Wは条件付きアプリケーションであるため、true _=!Tあるすべてのサブアレイを反転(反転)します。Tは、10(真)に事前初期化された変数で、を=!T意味し(T = !T)ます。そのため、真偽から始まり、新しい値を返す変数の値を切り替えます。つまり、偽、真、偽、真を返します。

テストスイートはこちら


11

ゼリー、24 19 15 13 11バイト

pS€żị"¥pỤị⁵

行数、列数、フラットリストを個別のコマンドライン引数として受け取ります。

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

使い方

pS€żị"¥pỤị⁵  Main link. Argument: m (rows), n (columns), A (list, flat)

p            Compute the Cartesian product [1, ..., m] × [1, ..., n]. This yields
             the indices of the matrix M, i.e., [[1, 1], [1, 2], ..., [m, n]].
 S€          Compute the sums of all index pairs.
       p     Yield the Cartesian product.
      ¥      Dyadic chain. Arguments: Sums, Cartesian product.
    ị"       For each index pair in the Cartesian product, retrieve the coordinate
             at the index of its sum, i.e., map [i, j] to i if i + j is odd and to
             j if i + j is even.
   ż         Zip the sums with the retrieved indices.
       Ụ     Sort [1, ..., mn] by the corresponding item in the resulting list.
        ị⁵   Retrieve the corresponding items from A.

Tsk。私は今、もっと短くすることができるかどうかわかりません。:-S
ギャレス

それは...私もしようとはしませんと言うことはありません
ギャレス・

JellyがObliqueをまだ継承していないのはなぜですか?APLグリフ?それともスカンジナビアøǿ
アダム

7

MATL28 27バイト

tZyZ}:w:!+-1y^7MGn/*-X:K#S)

ここで私の答えから適応。一般的な考え方は、入力と同じサイズの2D配列を作成し、ジグザグパスと同じ順序で増加する値で埋めることです。次に、その配列の線形化(平坦化)バージョンがソートされ、そのソートのインデックスが保持されます。これらは、ジグザグパスを生成するために入力に適用する必要があるインデックスです。

入力は次の形式です

[1 2 3; 5 6 4; 9 7 8; 1 2 3]

説明

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

t       % input 2D array. Duplicate
ZyZ}    % get size as length-2 vector. Split into two numbers: r, c
:       % range [1,2,...,c] as a row vector
w:!     % swap, range [1;2;...;r] as a column vector
+       % add with broadcast. Gives a 2D array
-1      % push -1
y^      % duplicate previous 2D array. Compute -1 raised to that
7M      % push [1;2;...;r] again
Gn/     % divide by input matrix size, that is, r*c
*       % multiply
-       % subtract
X:      % linearize 2D array into column array
K#S     % sort and push the indices of the sorting. Gives a column vector
)       % index input matrix with that column vector

4

Matlab、134バイト

電信のように、Matlabでコードを短くするために最善を尽くしました。

function V=z(M)
[m,n]=size(M);
a=(1:m)'*ones(1,n);
b=ones(m,1)*(1:n);
A=a+b-1;
B=a-b;
C=(A.^2+(-1).^A.*B+1);
[~,I]=sort(C(:));
V=M(:);
V=V(I)';

ノート:

  1. Mm×n行列です。
  2. abは、両方とも同じサイズの行列でありM、の各行はaその行番号に等しい数値で構成され、の各列はその列番号にb等しくなります。したがって、a+ bは、その要素が行番号と列番号の合計に等しい行列ですmatrix(p,q)=p+q
  3. したがって、A(p,q)=p+q-1; およびB(p,q)=p-q
  4. C以下の方程式として数学的に述べられています。 ジグザグに増加する行列 この方程式を使用すると、次のようにジグザグに増加する行列を作成できます。
C =
     1     2     6     7
     3     5     8    14
     4     9    13    18
    10    12    19    25
  1. Cジグザグ化された結果のMの要素の順序を示します。次に、[~,I]=sort(C(:));順序を返します。Iつまり、V=V(I)'が結果になります。

はい、見つけました。更新しました。
国陽Q

@AlexA。ありがとう、アレックス。私はこれに慣れていないので、できるだけ短くしたいのですが、スニペットにします。今、コードを修正しました。
国陽Q

いいね。素敵な最初の投稿!:)
アレックスA.

3

JavaScript(SpiderMonkey 30 +)、99バイト

x=>[for(y of[...x,...x[0]].keys())for(z of Array(y+1).keys())if(a=x[y%2?z:y-z])if(b=a[y%2?y-z:z])b]

Firefox 44でテスト済み。入力を2D配列として受け取ります。


3

Python 2、84バイト

lambda N,w,h:[N[i*w+s-i]for s in range(w+h+1)for i in range(h)[::s%2*2-1]if-1<s-i<w]

nimiの答えを移植する。指定された幅と高さでフラット配列を取ります。xsotは1バイトを保存しました。


88バイト:

lambda M,w,h:[M[i]for i in sorted(range(w*h),key=lambda i:(i/w+i%w,-i*(-1)**(i/w+i%w)))]

指定された幅と高さでフラット配列を取ります。(i/w,i%w)行と列が奇数か偶数かに基づいて、対応する2D座標を合計の増加順にジグザグ順に並べ替えて、対角線を取得します。


if条件をさらに短縮できます。
xsot

@xsotすてきなキャッチ。
xnor

3

Haskell、79 78 73バイト

(m#h)w=[m!!(y*w+x-y)|x<-[0..h+w],y<-g!!x$[0..x],y<h,x-y<w]
g=reverse:id:g

入力は、行と列の数を持つフラットリストです(例:( [1,2,6,3,1,2,5,9,4,7,8,3] # 2) 6->)[1,2,5,9,6,3,4,7,1,2,8,3]

仕組み:2つのネストされたループでマトリックス(h行、w列)のx座標とy座標を調べます。

  | 0 1 2 3 4 5 6 7 8    outer loop               Index is y*w+x-y, i.e.
--+------------------    x from 0 to h+w          the elements are accessed
0 | 1 2 6 3 1 2                                   in the following order:
1 | 5 9 4 7 8 3
2 |                                               1 2 4 6  8 10 
3 |                                               3 5 7 9 11 12
4 |
5 |
6 |
7 | inner loop:
8 | y from 0 to x

すなわち、上/右から下/左へ、範囲外のインデックスをスキップします(yそしてとxを満たす必要がy<hありますx-y<w)。ときxにも、内側のループの順序が逆転している:yから行くxまで0。これを行うに[0..x]は、のxth要素であるy範囲の修正関数を選択し[reverse,id,reverse,id,...]ます。

編集:@xnorはループを再配置し、5バイトを保存しました。ありがとう!


できると思いますg=id:reverse:g
XNOR

マルチカチオンの括弧は、(y-x)*w問題を転置することでカットできます(m#h)w=[m!!(x*w+y-x)|y<-[0..h+w],x<-g!!y$[0..y],x<h,y-x<w] g=reverse:id:g。Pythonに翻訳すると、私が持っていたものよりも3文字節約できます。
xnor

1

Python 2 + NumPy、122バイト

認めます。私は先に働きました。残念ながら、この同じ方法を他の2つの関連する課題を解決するために簡単に変更することはできません...

import numpy
def f(m):w=len(m);print sum([list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))],[])

numpy配列を入力として受け取ります。リストを出力します。

オンラインで試す

説明:

def f(m):
    w=len(m)    # the height of the matrix, (at one point I thought it was the width)
    # get the anti-diagonals of the matrix. Reverse them if odd by mapping odd to -1
    d=[list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))]
            # w+len(m[0]) accounts for the width of the matrix. Works if it's too large.
    print sum(d,[]) # join the lists

ラムダは同じ長さです:

import numpy
lambda m:sum([list(m[::-1,:].diagonal(i)[::(i+len(m)+1)%2*-2+1])for i in range(-len(m),len(m)+len(m[0]))],[])

1

Python 3、131 118 115 107バイト

私と同じプリンシペに基づいて解答Deusoviの挑戦

入力行列にゼロを含めることはできないと思います

e=enumerate
lambda s:[k for j,i in e(zip(*[([0]*n+i+[0]*len(s))for n,i in e(s)]))for k in i[::j%2*2-1]if k]

説明

使い方 :

            pad with 0      transpose    remove 0    reverse line           concatenate 
                                                     with even index
1 2 3       1 2 3 0 0        1 0 0        1            1                
4 5 6   --> 0 4 5 6 0    --> 2 4 0    --> 2 4     -->  2 4              -->  1 2 4 7 5 3 6 8 9
7 8 9       0 0 7 8 9        3 5 7        3 5 7        7 5 3             
                             0 6 8        6 8          6 8               
                             0 0 9        9            9

結果

>>> [print([i,f(i)]) for i in [[[1]], [[1, 2], [3, 1]], [[1, 2, 3, 1]], [[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]], [[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]], [[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]], [[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]], [[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]]]]
# [input,                                                          output]
[[[1]],                                                            [1]]
[[[1, 2], [3, 1]],                                                 [1, 2, 3, 1]]
[[[1, 2, 3, 1]],                                                   [1, 2, 3, 1]]
[[[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]],                     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]],                       [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]],                         [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]],                           [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]],     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]

なければならないreverse even lineことreverse odd linesの代わりに?
nwp

@nwpインデックスは0から始まります^^
エルワン

ああ、あなたは行の長さではなく、行番号について話しています。混乱してしまいました、ごめんなさい。
nwp

@nwp np、ところで混乱を避けるためにそれを変更しました
エルワン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.