Bir Matrisi Zikzakla


43

Sıkıştırma algoritmasının bir parçası olarak, JPEG standardı bir matrisin dönüşümlü yöndeki antidiagonal boyunca bir vektöre ayrılmasını sağlar:

görüntü tanımını buraya girin

Senin görevin bir matris (mutlaka kare değil) almak ve onu kontrolsüz biçimde iade etmektir. Örnek olarak:

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

vermeli

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

kurallar

Matris öğelerinin, değerinden daha küçük tamsayılar olduğunu varsayabilirsiniz 10.

STDIN (veya en yakın alternatif), komut satırı argümanı veya işlev argümanı yoluyla giriş alarak ve sonucu STDOUT (veya en yakın alternatif), fonksiyon dönüş değeri veya function (out) parametresi ile çıktı alarak bir program veya işlev yazabilirsiniz.

Giriş matrisi herhangi bir uygun, açık, iç içe liste veya dize biçiminde veya her iki matris boyutuyla birlikte düz bir liste halinde verilebilir. (Ya da elbette, eğer dilinizde varsa, bir matris türü olarak.)

Çıktı vektörü herhangi bir uygun, açık, düz bir liste veya dize formatında olabilir.

Standart kuralları geçerlidir.

Test Kılıfları

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

İlgili Zorluklar


1
Giriş J'de gerçek bir matris olabilir mi? Yoksa iç içe geçmiş listelerden işlevin bir parçası olarak bir matrise dönüştürülmesi gerekir mi?
Gareth,

4
Matrisi bir 2D dizi olarak alırsak, boyutları hala girdi olarak alabilir miyiz?
xnor

1
@Gareth evet, girdi olarak bir matris türü alabilir.
Martin Ender

1
@xnor Hmmm, bu biraz daha zor. Bu kadar fazla bilgiyi almak, girdiyi ön işlemden geçirmek için bir parça gider gibi hissediyorum.
Martin Ender

Dilin yerel düzeni buysa , düz liste sütun ana sırada olabilir mi?
Luis Mendo

Yanıtlar:


27

J, 31 30 14 12 11 bayt

[:;<@|.`</.

Ych . Çok büyük.

Giriş olarak bir matris alır.

açıklama

J'nin burada bir avantajı var. Eğik çizgileri sırayla alan ve onlara bir fiil uygulayan eğik ( /.) adında bir komut var . Bu durumda dönüşümlü olarak iki fiil uygulamak için bir hata kullanıyorum: <( kutu ) ve <@|.( geri ve kutu). Sonra kullanarak kutudan çıkarma herşeyin meselesi ;( raze ).


26
J, anlamam için İngilizce'de ileri bir dereceye ihtiyacım olduğunu hissettiren tek dildir.
Alex A.

2
@AlexA. btw, "command" kelimesi "adverb" olmalıydı.
Adám

11

Pyth, 24 23 21 20 19 18 17 bayt

ssm_W=!Td.T+LaYkQ

Alternatif 17 bayt sürümü: 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)

Sayesinde @FryAmTheEggman bir byte için, @Jakube 2 byte için ve @isaacg bir byte için!

Yukarıda belirtilen "kara büyü" nin açıklaması: m_W=!Tdaslında diğer tüm alt dizileri tersine çevirir. Bunu _W=!Ther alt dizinin üzerinde eşleyerek yapar ; Wkoşullu uygulamadır, bu nedenle doğru olan _tüm alt dizileri s (tersine çevirir) =!T. Ton'a önceden başlatılmış bir değişkendir (truthy) ve =!Taraçlar (T = !T). Bu nedenle, gerçeği başlatan ve yeni değeri döndüren bir değişkenin değerini değiştirir, bu, falsy, truthy, falsy, truthy ... (bu fikir için Jakube'a verilen krediyi döndürmek) arasında geçiş yapacağı anlamına gelir.

Burada test süiti .


11

Jöle, 24 19 15 13 11 bayt

pS€żị"¥pỤị⁵

Komut satırı argümanları olarak satır sayısını, sütun sayısını ve düz bir listeyi alır.

Çevrimiçi deneyin!

Nasıl çalışır

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. Şimdi benimkileri daha kısa tutabileceğimden emin değilim. : -S
Gareth

Bu bir daha denemeyeceğim anlamına gelmez ...
Gareth

Jelly neden henüz Oblique'i devralmadı? APL gliflerini ve önerebilir miyim ? Ya da belki İskandinav øve ǿ?
Adám

7

MATL , 28 27 bayt

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

Buradaki cevabımdan uyarlandı . Genel fikir, zig-zag yolu ile aynı sırada artan değerlerle dolu, girişle aynı boyutta bir 2D dizi oluşturmaktır. Ardından, bu dizinin doğrusallaştırılmış (düzleştirilmiş) sürümü sıralanır ve bu sıralamanın dizinleri tutulur. Bunlar, zig-zag yolunu üretmek için girişe uygulanması gereken endekslerdir.

Giriş formunda

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

açıklama

Çevrimiçi deneyin!

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 bayt

Telgraf gibi, Matlab’daki kodumu kısaltmak için elimden geleni yaptım.

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)';

Notlar:

  1. Mbir m×nmatristir.
  2. ave bher ikisi de aynı büyüklüğe sahip matrislerdir M, her bir satır satır anumarasına eşit sayılardan oluşur, her sütun bise sütun numarasına eşittir. Bu nedenle, a+ b, elemanı satır ve sütun sayısının toplamına eşit olan bir matristir, yani matrix(p,q)=p+q.
  3. Böylece A(p,q)=p+q-1; ve B(p,q)=p-q.
  4. Cmatematiksel olarak aşağıdaki denklem olarak belirtilmiştir. Zikzaklı şekilde artan matris denklem ile, aşağıda gösterildiği gibi zikzak olarak artan bir matris yapılabilir.
C =
     1     2     6     7
     3     5     8    14
     4     9    13    18
    10    12    19    25
  1. CZikzaklaştırılmış sonuçlarda M elementlerinin sırasını gösterir. Ardından, [~,I]=sort(C(:));yani, düzen verir I, böylece, V=V(I)'sonucudur.

Evet, yeni buldum, şimdi güncelliyorum.
Guoyang Qin

@AlexA. Teşekkürler Alex. Çünkü bunun için yeniyim ve mümkün olduğu kadar kısaltmak istiyorum ancak bir pasajı yapmak istiyorum. Şimdi kodumu düzelttim.
Guoyang Qin

İyi görünüyor. Güzel ilk mesaj! :)
Alex A.

3

JavaScript (SpiderMonkey 30+), 99 bayt

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'te test edilmiştir. Girdiyi 2D dizi olarak alır.


3

Python 2, 84 bayt

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]

Porting nimi cevabını . Verilen genişlik ve yüksekliğe sahip düz bir dizi alır. xsot bir bayt kaydetti.


88 bayt:

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

Verilen genişlik ve yüksekliğe sahip düz bir dizi alır. Karşılık gelen 2B koordinatları (i/w,i%w), satır artı sütunun tek veya çift olmasına bağlı olarak, satır değerini artırarak veya azaltarak terazisi almak üzere, köşegenleri almak için artan toplam zikzak sırasına göre sıralar .


Eğer durum daha da kısaltılabilirse.
xsot

@ xsot Güzel yakala.
xnor

3

Haskell, 79 78 73 bayt

(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

Giriş, satır ve sütun sayısının bulunduğu düz bir listedir, örneğin ( [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].

Nasıl çalışır: iki iç içe döngüde matrisin x ve y koordinatlarını ( hsatırlar, wsütunlar) geçirin:

  | 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

yani yukarıdan / sağdan aşağı / sola, bağlı endekslerden atlamak ( yve xtatmin etmek y<hve x-y<w). Ne zaman xbile, iç döngünün sırası tersine olup: ygider xiçin 0. Bunu [0..x], xth elemanı olan y aralığı için değiştirici bir işlev seçerek yapıyorum [reverse,id,reverse,id,...].

Düzenleme: @xnor döngüleri yeniden düzenledi ve 5 bayt kaydetti. Teşekkürler!


Yapabileceğini düşünüyorum g=id:reverse:g.
xnor

Multication üzerinde parens (y-x)*wsorunu aktaran tarafından kesilebilir: (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'a çevirmek sahip olduğum şeyden 3 karakter kurtarıyor.
xnor

1

Python 2 + NumPy, 122 bayt

İtiraf ediyorum. Ben ileri çalıştım. Ne yazık ki, bu aynı yöntem diğer ilgili 2 sorunu çözmek için kolayca değiştirilemez ...

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]))],[])

Giriş olarak bir numpy dizi alır. Bir liste çıkarır.

Çevrimiçi deneyin

Açıklama:

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

Bir lambda aynı uzunluktadır:

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 bayt

Benim aynı prensipte dayanarak cevap ait Deusovi en meydan

Girdi matrisinde sıfır olamayacağımızı varsayıyorum.

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]

açıklama

nasıl çalışır :

            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

Sonuçlar

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

Meli reverse even lineolmak reverse odd linesyerine?
nwp

@ nwp endeksi 0 ^^ ile başlıyor
Erwan

Ah, hat numaralarından bahsediyorsun, hat uzunluğundan değil. Bunları karıştırdım, üzgünüm.
saat

@ nwp np, btw Kargaşayı önlemek için değiştirdim
Erwan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.